Updated tests from develop branch.
This commit is contained in:
parent
4b75601caa
commit
5f8e8fe91d
|
@ -0,0 +1,92 @@
|
||||||
|
package org.ethereum;
|
||||||
|
|
||||||
|
import org.ethereum.config.SystemProperties;
|
||||||
|
import org.ethereum.facade.Ethereum;
|
||||||
|
import org.hibernate.SessionFactory;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.jdbc.datasource.DriverManagerDataSource;
|
||||||
|
import org.springframework.orm.hibernate4.LocalSessionFactoryBuilder;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Roman Mandeleil
|
||||||
|
* @since 16.11.2014
|
||||||
|
*/
|
||||||
|
public class TestContext {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger("test");
|
||||||
|
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public SessionFactory sessionFactory() throws SQLException {
|
||||||
|
|
||||||
|
logger.info("loading context");
|
||||||
|
|
||||||
|
LocalSessionFactoryBuilder builder =
|
||||||
|
new LocalSessionFactoryBuilder(dataSource());
|
||||||
|
builder.scanPackages("org.ethereum.db")
|
||||||
|
.addProperties(getHibernateProperties());
|
||||||
|
|
||||||
|
return builder.buildSessionFactory();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Properties getHibernateProperties() {
|
||||||
|
|
||||||
|
Properties prop = new Properties();
|
||||||
|
|
||||||
|
if (SystemProperties.CONFIG.databaseReset())
|
||||||
|
prop.put("hibernate.hbm2ddl.auto", "create");
|
||||||
|
|
||||||
|
prop.put("hibernate.format_sql", "true");
|
||||||
|
|
||||||
|
// todo: useful but annoying consider define by system.properties
|
||||||
|
// prop.put("hibernate.show_sql", "true");
|
||||||
|
prop.put("hibernate.dialect",
|
||||||
|
"org.hibernate.dialect.HSQLDialect");
|
||||||
|
|
||||||
|
prop.put("hibernate.connection.autocommit",
|
||||||
|
"true");
|
||||||
|
|
||||||
|
return prop;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
|
||||||
|
<property name="entityManagerFactory" ref="entityManagerFactory" />
|
||||||
|
</bean>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
@Bean(name = "dataSource")
|
||||||
|
public DriverManagerDataSource dataSource() {
|
||||||
|
|
||||||
|
logger.info("Connecting to the block store");
|
||||||
|
|
||||||
|
System.setProperty("hsqldb.reconfig_logging", "false");
|
||||||
|
|
||||||
|
String url =
|
||||||
|
String.format("jdbc:hsqldb:file:./%s/blockchain/blockchain.db;" +
|
||||||
|
"create=%s;hsqldb.default_table_type=cached",
|
||||||
|
|
||||||
|
SystemProperties.CONFIG.databaseDir(),
|
||||||
|
SystemProperties.CONFIG.databaseReset());
|
||||||
|
|
||||||
|
DriverManagerDataSource ds = new DriverManagerDataSource();
|
||||||
|
ds.setDriverClassName("org.hsqldb.jdbcDriver");
|
||||||
|
ds.setUrl(url);
|
||||||
|
ds.setUsername("sa");
|
||||||
|
|
||||||
|
return ds;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
Ethereum eth;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,88 @@
|
||||||
|
package org.ethereum.blockstore;
|
||||||
|
|
||||||
|
import org.ethereum.core.Block;
|
||||||
|
import org.ethereum.db.InMemoryBlockStore;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author: Roman Mandeleil
|
||||||
|
* Created on: 30/01/2015 11:04
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class InMemoryBlockStoreTest {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger("test");
|
||||||
|
private InMemoryBlockStore blockStore;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() throws URISyntaxException, IOException {
|
||||||
|
|
||||||
|
blockStore = new InMemoryBlockStore();
|
||||||
|
URL scenario1 = ClassLoader
|
||||||
|
.getSystemResource("blockstore/load.dmp");
|
||||||
|
|
||||||
|
File file = new File(scenario1.toURI());
|
||||||
|
List<String> strData = Files.readAllLines(file.toPath(), StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
for (String blockRLP : strData) {
|
||||||
|
Block block = new Block(
|
||||||
|
Hex.decode(blockRLP));
|
||||||
|
logger.trace("adding block.hash: [{}] block.number: [{}]",
|
||||||
|
block.getShortHash(),
|
||||||
|
block.getNumber());
|
||||||
|
blockStore.saveBlock(block, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSaving8003Blocks() {
|
||||||
|
|
||||||
|
Block bestBlock = blockStore.getBestBlock();
|
||||||
|
Long bestIndex = blockStore.getBestBlock().getNumber();
|
||||||
|
Long firstIndex = bestIndex - InMemoryBlockStore.MAX_BLOCKS;
|
||||||
|
|
||||||
|
assertTrue(bestIndex == 8003);
|
||||||
|
assertTrue(firstIndex == 7003);
|
||||||
|
|
||||||
|
assertTrue(blockStore.getBlockByNumber(7000) == null);
|
||||||
|
assertTrue(blockStore.getBlockByNumber(8004) == null);
|
||||||
|
|
||||||
|
Block byHashBlock = blockStore.getBlockByHash(bestBlock.getHash());
|
||||||
|
assertTrue(bestBlock.getNumber() == byHashBlock.getNumber());
|
||||||
|
|
||||||
|
byte[] hashFor7500 = blockStore.getBlockByNumber(7500).getHash();
|
||||||
|
Block block7500 = blockStore.getBlockByHash(hashFor7500);
|
||||||
|
assertTrue(block7500.getNumber() == 7500);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testListOfHashes(){
|
||||||
|
|
||||||
|
Block block = blockStore.getBlockByNumber(7500);
|
||||||
|
byte[] hash = block.getHash();
|
||||||
|
|
||||||
|
List<byte[]> hashes = blockStore.getListOfHashesStartFrom(hash, 700);
|
||||||
|
|
||||||
|
byte[] lastHash = hashes.get(hashes.size() - 1);
|
||||||
|
|
||||||
|
assertEquals(Hex.toHexString(blockStore.getBestBlock().getHash()),
|
||||||
|
Hex.toHexString(lastHash));
|
||||||
|
|
||||||
|
assertTrue(hashes.size() == 504);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package org.ethereum.core;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class AccountStateTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetEncoded() {
|
||||||
|
String expected = "f85e809"
|
||||||
|
+ "a0100000000000000000000000000000000000000000000000000"
|
||||||
|
+ "a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
|
||||||
|
+ "a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470";
|
||||||
|
AccountState acct = new AccountState(BigInteger.ZERO, BigInteger.valueOf(2).pow(200));
|
||||||
|
assertEquals(expected, Hex.toHexString(acct.getEncoded()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,113 @@
|
||||||
|
package org.ethereum.core;
|
||||||
|
|
||||||
|
import org.ethereum.trie.SecureTrie;
|
||||||
|
import org.ethereum.trie.Trie;
|
||||||
|
import org.json.simple.JSONObject;
|
||||||
|
import org.json.simple.parser.JSONParser;
|
||||||
|
import org.json.simple.parser.ParseException;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
|
||||||
|
public class BlockTest {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger("test");
|
||||||
|
|
||||||
|
|
||||||
|
// https://github.com/ethereum/tests/blob/71d80bd63aaf7cee523b6ca9d12a131698d41e98/BasicTests/genesishashestest.json
|
||||||
|
private String GENESIS_RLP = "f901f8f901f3a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a09178d0f23c965d81f0834a4c72c6253ce6830f4022b1359aaebfc1ecba442d4ea056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808080a0000000000000000000000000000000000000000000000000000000000000000088000000000000002ac0c0";
|
||||||
|
private String GENESIS_HASH = "fd4af92a79c7fc2fd8bf0d342f2e832e1d4f485c85b9152d2039e03bc604fdca";
|
||||||
|
private String GENESIS_STATE_ROOT = "9178d0f23c965d81f0834a4c72c6253ce6830f4022b1359aaebfc1ecba442d4e";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static String TEST_GENESIS =
|
||||||
|
"{" +
|
||||||
|
"'0000000000000000000000000000000000000001': { 'wei': '1' }" +
|
||||||
|
"'0000000000000000000000000000000000000002': { 'wei': '1' }" +
|
||||||
|
"'0000000000000000000000000000000000000003': { 'wei': '1' }" +
|
||||||
|
"'0000000000000000000000000000000000000004': { 'wei': '1' }" +
|
||||||
|
"'dbdbdb2cbd23b783741e8d7fcf51e459b497e4a6': { 'wei': '1606938044258990275541962092341162602522202993782792835301376' }" +
|
||||||
|
"'e6716f9544a56c530d868e4bfbacb172315bdead': { 'wei': '1606938044258990275541962092341162602522202993782792835301376' }" +
|
||||||
|
"'b9c015918bdaba24b4ff057a92a3873d6eb201be': { 'wei': '1606938044258990275541962092341162602522202993782792835301376' }" +
|
||||||
|
"'1a26338f0d905e295fccb71fa9ea849ffa12aaf4': { 'wei': '1606938044258990275541962092341162602522202993782792835301376' }" +
|
||||||
|
"'2ef47100e0787b915105fd5e3f4ff6752079d5cb': { 'wei': '1606938044258990275541962092341162602522202993782792835301376' }" +
|
||||||
|
"'cd2a3d9f938e13cd947ec05abc7fe734df8dd826': { 'wei': '1606938044258990275541962092341162602522202993782792835301376' }" +
|
||||||
|
"'6c386a4b26f73c802f34673f7248bb118f97424a': { 'wei': '1606938044258990275541962092341162602522202993782792835301376' }" +
|
||||||
|
"'e4157b34ea9615cfbde6b4fda419828124b70c78': { 'wei': '1606938044258990275541962092341162602522202993782792835301376' }" +
|
||||||
|
"}";
|
||||||
|
|
||||||
|
static {
|
||||||
|
TEST_GENESIS = TEST_GENESIS.replace("'", "\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGenesisFromRLP() {
|
||||||
|
// from RLP encoding
|
||||||
|
byte[] genesisBytes = Hex.decode(GENESIS_RLP);
|
||||||
|
Block genesisFromRLP = new Block(genesisBytes);
|
||||||
|
Block genesis = Genesis.getInstance();
|
||||||
|
assertEquals(Hex.toHexString(genesis.getHash()), Hex.toHexString(genesisFromRLP.getHash()));
|
||||||
|
assertEquals(Hex.toHexString(genesis.getParentHash()), Hex.toHexString(genesisFromRLP.getParentHash()));
|
||||||
|
assertEquals(Hex.toHexString(genesis.getStateRoot()), Hex.toHexString(genesisFromRLP.getStateRoot()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGenesisFromNew() {
|
||||||
|
Block genesis = Genesis.getInstance();
|
||||||
|
logger.info(genesis.toString());
|
||||||
|
|
||||||
|
logger.info("genesis hash: [{}]", Hex.toHexString(genesis.getHash()));
|
||||||
|
logger.info("genesis rlp: [{}]", Hex.toHexString(genesis.getEncoded()));
|
||||||
|
|
||||||
|
assertEquals(GENESIS_HASH, Hex.toHexString(genesis.getHash()));
|
||||||
|
assertEquals(GENESIS_RLP, Hex.toHexString(genesis.getEncoded()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGenesisPremineData() {
|
||||||
|
Genesis genesis = (Genesis) Genesis.getInstance();
|
||||||
|
Collection<AccountState> accounts = genesis.getPremine().values();
|
||||||
|
assertTrue(accounts.size() == 12);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPremineFromJSON() throws ParseException {
|
||||||
|
|
||||||
|
JSONParser parser = new JSONParser();
|
||||||
|
JSONObject genesisMap = (JSONObject) parser.parse(TEST_GENESIS);
|
||||||
|
|
||||||
|
Set<String> keys = genesisMap.keySet();
|
||||||
|
|
||||||
|
Trie state = new SecureTrie(null);
|
||||||
|
|
||||||
|
for (String key : keys) {
|
||||||
|
|
||||||
|
JSONObject val = (JSONObject) genesisMap.get(key);
|
||||||
|
String denom = (String) val.keySet().toArray()[0];
|
||||||
|
String value = (String) val.values().toArray()[0];
|
||||||
|
|
||||||
|
BigInteger wei = Denomination.valueOf(denom.toUpperCase()).value().multiply(new BigInteger(value));
|
||||||
|
|
||||||
|
AccountState acctState = new AccountState(BigInteger.ZERO, wei);
|
||||||
|
state.update(Hex.decode(key), acctState.getEncoded());
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("root: " + Hex.toHexString(state.getRootHash()));
|
||||||
|
assertEquals(GENESIS_STATE_ROOT, Hex.toHexString(state.getRootHash()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
package org.ethereum.core;
|
||||||
|
|
||||||
|
import org.ethereum.crypto.HashUtil;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Roman Mandeleil
|
||||||
|
* @since 20.11.2014
|
||||||
|
*/
|
||||||
|
public class BloomTest {
|
||||||
|
|
||||||
|
|
||||||
|
@Test /// based on http://bit.ly/1MtXxFg
|
||||||
|
public void test1(){
|
||||||
|
|
||||||
|
byte[] address = Hex.decode("095e7baea6a6c7c4c2dfeb977efac326af552d87");
|
||||||
|
Bloom addressBloom = Bloom.create(HashUtil.sha3(address));
|
||||||
|
|
||||||
|
byte[] topic = Hex.decode("0000000000000000000000000000000000000000000000000000000000000000");
|
||||||
|
Bloom topicBloom = Bloom.create(HashUtil.sha3(topic));
|
||||||
|
|
||||||
|
Bloom totalBloom = new Bloom();
|
||||||
|
totalBloom.or(addressBloom);
|
||||||
|
totalBloom.or(topicBloom);
|
||||||
|
|
||||||
|
|
||||||
|
Assert.assertEquals(
|
||||||
|
"00000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000040000000000000000000000000000000000000000000000000000000",
|
||||||
|
totalBloom.toString()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test2() {
|
||||||
|
// todo: more testing
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test3() {
|
||||||
|
// todo: more testing
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test4() {
|
||||||
|
// todo: more testing
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,93 @@
|
||||||
|
package org.ethereum.core;
|
||||||
|
|
||||||
|
|
||||||
|
import org.ethereum.config.SystemProperties;
|
||||||
|
import org.ethereum.db.BlockStore;
|
||||||
|
import org.ethereum.db.InMemoryBlockStore;
|
||||||
|
import org.ethereum.manager.WorldManager;
|
||||||
|
import org.hibernate.SessionFactory;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
import org.springframework.test.context.support.AnnotationConfigContextLoader;
|
||||||
|
import org.springframework.transaction.annotation.Propagation;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.ethereum.TestContext;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
|
@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
|
||||||
|
public class ImportTest {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger("test");
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@ComponentScan(basePackages = "org.ethereum")
|
||||||
|
static class ContextConfiguration extends TestContext {
|
||||||
|
static {
|
||||||
|
SystemProperties.CONFIG.setDataBaseDir("test_db/" + ImportTest.class);
|
||||||
|
SystemProperties.CONFIG.setDatabaseReset(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@Transactional(propagation = Propagation.SUPPORTS)
|
||||||
|
public BlockStore blockStore(SessionFactory sessionFactory){
|
||||||
|
return new InMemoryBlockStore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
WorldManager worldManager;
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void close(){
|
||||||
|
worldManager.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testScenario1() throws URISyntaxException, IOException {
|
||||||
|
|
||||||
|
logger.error("Started");
|
||||||
|
|
||||||
|
BlockchainImpl blockchain = (BlockchainImpl) worldManager.getBlockchain();
|
||||||
|
|
||||||
|
URL scenario1 = ClassLoader
|
||||||
|
.getSystemResource("blockload/scenario1.dmp");
|
||||||
|
|
||||||
|
File file = new File(scenario1.toURI());
|
||||||
|
List<String> strData = Files.readAllLines(file.toPath(), StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
byte[] root = Genesis.getInstance().getStateRoot();
|
||||||
|
for (String blockRLP : strData) {
|
||||||
|
Block block = new Block(
|
||||||
|
Hex.decode(blockRLP));
|
||||||
|
logger.info("sending block.hash: {}", Hex.toHexString(block.getHash()));
|
||||||
|
blockchain.tryToConnect(block);
|
||||||
|
root = block.getStateRoot();
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("asserting root state is: {}", Hex.toHexString(root));
|
||||||
|
assertEquals(Hex.toHexString(root),
|
||||||
|
Hex.toHexString(worldManager.getRepository().getRoot()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
package org.ethereum.core;
|
||||||
|
|
||||||
|
import org.ethereum.vm.LogInfo;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Roman Mandeleil
|
||||||
|
* @since 05.12.2014
|
||||||
|
*/
|
||||||
|
public class LogInfoTest {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger("test");
|
||||||
|
|
||||||
|
@Test // rlp decode
|
||||||
|
public void test_1() {
|
||||||
|
|
||||||
|
// LogInfo{address=d5ccd26ba09ce1d85148b5081fa3ed77949417be, topics=[000000000000000000000000459d3a7595df9eba241365f4676803586d7d199c 436f696e73000000000000000000000000000000000000000000000000000000 ], data=}
|
||||||
|
byte[] rlp = Hex.decode("f85a94d5ccd26ba09ce1d85148b5081fa3ed77949417bef842a0000000000000000000000000459d3a7595df9eba241365f4676803586d7d199ca0436f696e7300000000000000000000000000000000000000000000000000000080");
|
||||||
|
LogInfo logInfo = new LogInfo(rlp);
|
||||||
|
|
||||||
|
assertEquals("d5ccd26ba09ce1d85148b5081fa3ed77949417be",
|
||||||
|
Hex.toHexString(logInfo.getAddress()));
|
||||||
|
assertEquals("", Hex.toHexString(logInfo.getData()));
|
||||||
|
|
||||||
|
assertEquals("000000000000000000000000459d3a7595df9eba241365f4676803586d7d199c",
|
||||||
|
logInfo.getTopics().get(0).toString());
|
||||||
|
assertEquals("436f696e73000000000000000000000000000000000000000000000000000000",
|
||||||
|
logInfo.getTopics().get(1).toString());
|
||||||
|
|
||||||
|
logger.info("{}", logInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // rlp decode
|
||||||
|
public void test_2() {
|
||||||
|
|
||||||
|
LogInfo log = new LogInfo(Hex.decode("d5ccd26ba09ce1d85148b5081fa3ed77949417be"), null, null);
|
||||||
|
assertEquals("d794d5ccd26ba09ce1d85148b5081fa3ed77949417bec080", Hex.toHexString(log.getEncoded()));
|
||||||
|
|
||||||
|
logger.info("{}", log);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Ignore //TODO #POC9
|
||||||
|
@Test // rlp decode
|
||||||
|
public void test_3() {
|
||||||
|
|
||||||
|
// LogInfo{address=f2b1a404bcb6112a0ff2c4197cb02f3de40018b3, topics=[5a360139cff27713da0fe18a2100048a7ce1b7700c953a82bc3ff011437c8c2a 588d7ddcc06c14843ea68e690dfd4ec91ba09a8ada15c5b7fa6fead9c8befe4b ], data=}
|
||||||
|
byte[] rlp = Hex.decode("f85a94f2b1a404bcb6112a0ff2c4197cb02f3de40018b3f842a05a360139cff27713da0fe18a2100048a7ce1b7700c953a82bc3ff011437c8c2aa0588d7ddcc06c14843ea68e690dfd4ec91ba09a8ada15c5b7fa6fead9c8befe4b80");
|
||||||
|
LogInfo logInfo = new LogInfo(rlp);
|
||||||
|
|
||||||
|
assertEquals("f2b1a404bcb6112a0ff2c4197cb02f3de40018b3",
|
||||||
|
Hex.toHexString(logInfo.getAddress()));
|
||||||
|
|
||||||
|
assertEquals("00800000000000000010000000000000000000000000002000000000000000000012000000100000000050000020000000000000000000000000000000000000",
|
||||||
|
logInfo.getBloom().toString());
|
||||||
|
|
||||||
|
assertEquals("f85a94f2b1a404bcb6112a0ff2c4197cb02f3de40018b3f842a05a360139cff27713da0fe18a2100048a7ce1b7700c953a82bc3ff011437c8c2aa0588d7ddcc06c14843ea68e690dfd4ec91ba09a8ada15c5b7fa6fead9c8befe4b80",
|
||||||
|
Hex.toHexString(logInfo.getEncoded()));
|
||||||
|
|
||||||
|
logger.info("{}", logInfo);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,126 @@
|
||||||
|
package org.ethereum.core;
|
||||||
|
|
||||||
|
|
||||||
|
import org.ethereum.crypto.HashUtil;
|
||||||
|
import org.ethereum.datasource.HashMapDB;
|
||||||
|
import org.ethereum.db.ByteArrayWrapper;
|
||||||
|
import org.ethereum.trie.Trie;
|
||||||
|
import org.ethereum.trie.TrieImpl;
|
||||||
|
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
|
||||||
|
public class StateTest {
|
||||||
|
|
||||||
|
private static final String GENESIS_STATE_ROOT = "7e204dc9cfb7acdf062ff0b8052f7fcb0b7e6593754773967932ce458d134af3";
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger("test");
|
||||||
|
|
||||||
|
|
||||||
|
@Ignore //TODO #POC9
|
||||||
|
@Test
|
||||||
|
public void testGenesisAccounts() {
|
||||||
|
Trie trie = generateGenesisState();
|
||||||
|
assertEquals(GENESIS_STATE_ROOT, Hex.toHexString(trie.getRootHash()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Ignore
|
||||||
|
@Test // calc state after applying first tx on genesis
|
||||||
|
public void test2() {
|
||||||
|
|
||||||
|
// explanation:
|
||||||
|
// 0) create genesis
|
||||||
|
// 1) apply cost of tx to cd2a3d9f938e13cd947ec05abc7fe734df8dd826
|
||||||
|
// 2) create AccountState for 77045e71a7a2c50903d88e564cd72fab11e82051
|
||||||
|
// 3) minner gets the gas + coinbase ==> 6260000000000000 + 1500000000000000000
|
||||||
|
// 4) calc the root
|
||||||
|
|
||||||
|
Trie trie = generateGenesisState();
|
||||||
|
String expected = "c12b4d771fbcc0d56ec106f8d465d24b9d4c36d60275bbafa7d69694d6708660";
|
||||||
|
|
||||||
|
// Get and update sender in world state
|
||||||
|
byte[] cowAddress = Hex.decode("cd2a3d9f938e13cd947ec05abc7fe734df8dd826");
|
||||||
|
byte[] rlpEncodedState = trie.get(cowAddress);
|
||||||
|
AccountState account_1 = new AccountState(rlpEncodedState);
|
||||||
|
account_1.addToBalance(new BigInteger("-6260000000001000"));
|
||||||
|
account_1.incrementNonce();
|
||||||
|
trie.update(cowAddress, account_1.getEncoded());
|
||||||
|
|
||||||
|
// Add contract to world state
|
||||||
|
byte[] codeData = Hex.decode("61778e600054");
|
||||||
|
AccountState account_2 = new AccountState(BigInteger.ZERO, BigInteger.valueOf(1000));
|
||||||
|
account_2.setCodeHash(HashUtil.sha3(codeData));
|
||||||
|
byte[] contractAddress = Hex.decode("77045e71a7a2c50903d88e564cd72fab11e82051"); // generated based on sender + nonce
|
||||||
|
trie.update(contractAddress, account_2.getEncoded());
|
||||||
|
|
||||||
|
// this is saved in the db
|
||||||
|
// trie.update(HashUtil.sha3(codeData), codeData);
|
||||||
|
|
||||||
|
// Update miner in world state
|
||||||
|
byte[] minerAddress = Hex.decode("4c5f4d519dff3c16f0d54b6866e256fbbbc1a600");
|
||||||
|
AccountState account_3 = new AccountState(BigInteger.ZERO, new BigInteger("1506260000000000000"));
|
||||||
|
trie.update(minerAddress, account_3.getEncoded());
|
||||||
|
|
||||||
|
assertEquals(expected, Hex.toHexString(trie.getRootHash()));
|
||||||
|
|
||||||
|
|
||||||
|
/* *** GROSS DATA ***
|
||||||
|
|
||||||
|
BlockData [
|
||||||
|
hash=22cf863ab836a6f5c29389d2e77f4792a3b3b52908c98ed14b1cbe91491a3e36
|
||||||
|
parentHash=77ef4fdaf389dca53236bcf7f72698e154eab2828f86fbc4fc6cd9225d285c89
|
||||||
|
unclesHash=1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347
|
||||||
|
coinbase=4c5f4d519dff3c16f0d54b6866e256fbbbc1a600
|
||||||
|
stateHash=69c21ff84a5af0b53b11c61110a16d6ad43dad37b3eb29ae8e88c936eb06456a
|
||||||
|
txTrieHash=a77691cf47bec9021d3f027fc8ef2d51b758b600a79967154354b8e37108896f
|
||||||
|
difficulty=3ff000
|
||||||
|
number=1
|
||||||
|
minGasPrice=10000000000000
|
||||||
|
gasLimit=999023
|
||||||
|
gasUsed=626
|
||||||
|
timestamp=1401979976 (2014.06.05 15:52:56)
|
||||||
|
extraData=null
|
||||||
|
nonce=0000000000000000000000000000000000000000000000005d439960040e4505
|
||||||
|
|
||||||
|
TransactionReceipt[
|
||||||
|
TransactionData [ hash=1ee6fa3149a5e9c09b54009eb6e108aaa7ecd79483d57eedcf2dff93a1505588 nonce=null,
|
||||||
|
gasPrice=09184e72a000, gas=03e8, receiveAddress=0000000000000000000000000000000000000000, value=03e8,
|
||||||
|
data=60016000546006601160003960066000f261778e600054, signatureV=27,
|
||||||
|
signatureR=2b379f22050e3554c3fa5423d9040bb28dcc7f905300db4e67c03bcf9b27003c,
|
||||||
|
signatureS=59f47793e050974e6b5fca2848b19925637b883a012693b54d712f1c4f74def5
|
||||||
|
]
|
||||||
|
, postTxState=7fa5bd00f6e03b5a5718560f1e25179b227167585a3c3da06a48f554365fb527
|
||||||
|
, cumulativeGas=0272]
|
||||||
|
]
|
||||||
|
|
||||||
|
+++ 4c5f4d519dff3c16f0d54b6866e256fbbbc1a600:
|
||||||
|
+++ 77045e71a7a2c50903d88e564cd72fab11e82051: $[61,77,8e,60,0,54] ([])
|
||||||
|
* cd2a3d9f938e13cd947ec05abc7fe734df8dd826: #1 1606938044258990275541962092341162602522202987522792835300376 (-6260000000001000)
|
||||||
|
*/
|
||||||
|
|
||||||
|
assertEquals(expected, Hex.toHexString(trie.getRootHash()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Trie generateGenesisState() {
|
||||||
|
|
||||||
|
Trie trie = new TrieImpl(new HashMapDB());
|
||||||
|
Genesis genesis = (Genesis)Genesis.getInstance();
|
||||||
|
for (ByteArrayWrapper key : genesis.getPremine().keySet()) {
|
||||||
|
trie.update(key.getData(), genesis.getPremine().get(key).getEncoded());
|
||||||
|
}
|
||||||
|
|
||||||
|
return trie;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
package org.ethereum.core;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Roman Mandeleil
|
||||||
|
* @since 05.12.2014
|
||||||
|
*/
|
||||||
|
public class TransactionReceiptTest {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger("test");
|
||||||
|
|
||||||
|
|
||||||
|
@Test // rlp decode
|
||||||
|
public void test_1() {
|
||||||
|
|
||||||
|
byte[] rlp = Hex.decode("f8c4a0966265cc49fa1f10f0445f035258d116563931022a3570a640af5d73a214a8da822b6fb84000000010000000010000000000008000000000000000000000000000000000000000000000000000000000020000000000000014000000000400000000000440f85cf85a94d5ccd26ba09ce1d85148b5081fa3ed77949417bef842a0000000000000000000000000459d3a7595df9eba241365f4676803586d7d199ca0436f696e7300000000000000000000000000000000000000000000000000000080");
|
||||||
|
TransactionReceipt txReceipt = new TransactionReceipt(rlp);
|
||||||
|
|
||||||
|
assertEquals(1, txReceipt.getLogInfoList().size());
|
||||||
|
|
||||||
|
assertEquals("966265cc49fa1f10f0445f035258d116563931022a3570a640af5d73a214a8da",
|
||||||
|
Hex.toHexString(txReceipt.getPostTxState()));
|
||||||
|
|
||||||
|
assertEquals("2b6f",
|
||||||
|
Hex.toHexString(txReceipt.getCumulativeGas()));
|
||||||
|
|
||||||
|
assertEquals("00000010000000010000000000008000000000000000000000000000000000000000000000000000000000020000000000000014000000000400000000000440",
|
||||||
|
Hex.toHexString(txReceipt.getBloomFilter().getData()));
|
||||||
|
|
||||||
|
logger.info("{}", txReceipt);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,304 @@
|
||||||
|
package org.ethereum.core;
|
||||||
|
|
||||||
|
import org.ethereum.crypto.ECKey;
|
||||||
|
import org.ethereum.crypto.ECKey.MissingPrivateKeyException;
|
||||||
|
import org.ethereum.crypto.HashUtil;
|
||||||
|
import org.ethereum.vm.LogInfo;
|
||||||
|
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.spongycastle.util.BigIntegers;
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.NoSuchProviderException;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
@Ignore
|
||||||
|
public class TransactionTest {
|
||||||
|
|
||||||
|
|
||||||
|
@Test /* sign transaction https://tools.ietf.org/html/rfc6979 */
|
||||||
|
public void test1() throws NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException, IOException {
|
||||||
|
|
||||||
|
//python taken exact data
|
||||||
|
String txRLPRawData = "a9e880872386f26fc1000085e8d4a510008203e89413978aee95f38490e9769c39b2773ed763d9cd5f80";
|
||||||
|
// String txRLPRawData = "f82804881bc16d674ec8000094cd2a3d9f938e13cd947ec05abc7fe734df8dd8268609184e72a0006480";
|
||||||
|
|
||||||
|
byte[] cowPrivKey = Hex.decode("c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4");
|
||||||
|
ECKey key = ECKey.fromPrivate(cowPrivKey);
|
||||||
|
|
||||||
|
byte[] data = Hex.decode(txRLPRawData);
|
||||||
|
|
||||||
|
// step 1: serialize + RLP encode
|
||||||
|
// step 2: hash = sha3(step1)
|
||||||
|
byte[] txHash = HashUtil.sha3(data);
|
||||||
|
|
||||||
|
String signature = key.doSign(txHash).toBase64();
|
||||||
|
System.out.println(signature);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test /* achieve public key of the sender */
|
||||||
|
public void test2() throws Exception {
|
||||||
|
|
||||||
|
// cat --> 79b08ad8787060333663d19704909ee7b1903e58
|
||||||
|
// cow --> cd2a3d9f938e13cd947ec05abc7fe734df8dd826
|
||||||
|
|
||||||
|
BigInteger value = new BigInteger("1000000000000000000000");
|
||||||
|
|
||||||
|
byte[] privKey = HashUtil.sha3("cat".getBytes());
|
||||||
|
ECKey ecKey = ECKey.fromPrivate(privKey);
|
||||||
|
|
||||||
|
byte[] senderPrivKey = HashUtil.sha3("cow".getBytes());
|
||||||
|
|
||||||
|
byte[] gasPrice = Hex.decode("09184e72a000");
|
||||||
|
byte[] gas = Hex.decode("4255");
|
||||||
|
|
||||||
|
// Tn (nonce); Tp(pgas); Tg(gaslimi); Tt(value); Tv(value); Ti(sender); Tw; Tr; Ts
|
||||||
|
Transaction tx = new Transaction(null, gasPrice, gas, ecKey.getAddress(),
|
||||||
|
value.toByteArray(),
|
||||||
|
null);
|
||||||
|
|
||||||
|
tx.sign(senderPrivKey);
|
||||||
|
|
||||||
|
System.out.println("v\t\t\t: " + Hex.toHexString(new byte[]{tx.getSignature().v}));
|
||||||
|
System.out.println("r\t\t\t: " + Hex.toHexString(BigIntegers.asUnsignedByteArray(tx.getSignature().r)));
|
||||||
|
System.out.println("s\t\t\t: " + Hex.toHexString(BigIntegers.asUnsignedByteArray(tx.getSignature().s)));
|
||||||
|
|
||||||
|
System.out.println("RLP encoded tx\t\t: " + Hex.toHexString(tx.getEncoded()));
|
||||||
|
|
||||||
|
// retrieve the signer/sender of the transaction
|
||||||
|
ECKey key = ECKey.signatureToKey(tx.getHash(), tx.getSignature().toBase64());
|
||||||
|
|
||||||
|
System.out.println("Tx unsigned RLP\t\t: " + Hex.toHexString(tx.getEncodedRaw()));
|
||||||
|
System.out.println("Tx signed RLP\t\t: " + Hex.toHexString(tx.getEncoded()));
|
||||||
|
|
||||||
|
System.out.println("Signature public key\t: " + Hex.toHexString(key.getPubKey()));
|
||||||
|
System.out.println("Sender is\t\t: " + Hex.toHexString(key.getAddress()));
|
||||||
|
|
||||||
|
assertEquals("cd2a3d9f938e13cd947ec05abc7fe734df8dd826",
|
||||||
|
Hex.toHexString(key.getAddress()));
|
||||||
|
|
||||||
|
System.out.println(tx.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test /* achieve public key of the sender nonce: 01 */
|
||||||
|
public void test3() throws Exception {
|
||||||
|
|
||||||
|
// cat --> 79b08ad8787060333663d19704909ee7b1903e58
|
||||||
|
// cow --> cd2a3d9f938e13cd947ec05abc7fe734df8dd826
|
||||||
|
|
||||||
|
ECKey ecKey = ECKey.fromPrivate(HashUtil.sha3("cat".getBytes()));
|
||||||
|
byte[] senderPrivKey = HashUtil.sha3("cow".getBytes());
|
||||||
|
|
||||||
|
byte[] nonce = {0x01};
|
||||||
|
byte[] gasPrice = Hex.decode("09184e72a000");
|
||||||
|
byte[] gasLimit = Hex.decode("4255");
|
||||||
|
BigInteger value = new BigInteger("1000000000000000000000000");
|
||||||
|
|
||||||
|
Transaction tx = new Transaction(nonce, gasPrice, gasLimit,
|
||||||
|
ecKey.getAddress(), value.toByteArray(), null);
|
||||||
|
|
||||||
|
tx.sign(senderPrivKey);
|
||||||
|
|
||||||
|
System.out.println("v\t\t\t: " + Hex.toHexString(new byte[]{tx.getSignature().v}));
|
||||||
|
System.out.println("r\t\t\t: " + Hex.toHexString(BigIntegers.asUnsignedByteArray(tx.getSignature().r)));
|
||||||
|
System.out.println("s\t\t\t: " + Hex.toHexString(BigIntegers.asUnsignedByteArray(tx.getSignature().s)));
|
||||||
|
|
||||||
|
System.out.println("RLP encoded tx\t\t: " + Hex.toHexString(tx.getEncoded()));
|
||||||
|
|
||||||
|
// retrieve the signer/sender of the transaction
|
||||||
|
ECKey key = ECKey.signatureToKey(tx.getHash(), tx.getSignature().toBase64());
|
||||||
|
|
||||||
|
System.out.println("Tx unsigned RLP\t\t: " + Hex.toHexString(tx.getEncodedRaw()));
|
||||||
|
System.out.println("Tx signed RLP\t\t: " + Hex.toHexString(tx.getEncoded()));
|
||||||
|
|
||||||
|
System.out.println("Signature public key\t: " + Hex.toHexString(key.getPubKey()));
|
||||||
|
System.out.println("Sender is\t\t: " + Hex.toHexString(key.getAddress()));
|
||||||
|
|
||||||
|
assertEquals("cd2a3d9f938e13cd947ec05abc7fe734df8dd826",
|
||||||
|
Hex.toHexString(key.getAddress()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Testdata from: https://github.com/ethereum/tests/blob/master/txtest.json
|
||||||
|
String RLP_ENCODED_RAW_TX = "e88085e8d4a510008227109413978aee95f38490e9769c39b2773ed763d9cd5f872386f26fc1000080";
|
||||||
|
String RLP_ENCODED_UNSIGNED_TX = "eb8085e8d4a510008227109413978aee95f38490e9769c39b2773ed763d9cd5f872386f26fc1000080808080";
|
||||||
|
String HASH_TX = "328ea6d24659dec48adea1aced9a136e5ebdf40258db30d1b1d97ed2b74be34e";
|
||||||
|
String RLP_ENCODED_SIGNED_TX = "f86b8085e8d4a510008227109413978aee95f38490e9769c39b2773ed763d9cd5f872386f26fc10000801ba0eab47c1a49bf2fe5d40e01d313900e19ca485867d462fe06e139e3a536c6d4f4a014a569d327dcda4b29f74f93c0e9729d2f49ad726e703f9cd90dbb0fbf6649f1";
|
||||||
|
String KEY = "c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4";
|
||||||
|
byte[] testNonce = Hex.decode("");
|
||||||
|
byte[] testGasPrice = BigIntegers.asUnsignedByteArray(BigInteger.valueOf(1000000000000L));
|
||||||
|
byte[] testGasLimit = BigIntegers.asUnsignedByteArray(BigInteger.valueOf(10000));
|
||||||
|
byte[] testReceiveAddress = Hex.decode("13978aee95f38490e9769c39b2773ed763d9cd5f");
|
||||||
|
byte[] testValue = BigIntegers.asUnsignedByteArray(BigInteger.valueOf(10000000000000000L));
|
||||||
|
byte[] testData = Hex.decode("");
|
||||||
|
byte[] testInit = Hex.decode("");
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTransactionFromSignedRLP() throws Exception {
|
||||||
|
Transaction txSigned = new Transaction(Hex.decode(RLP_ENCODED_SIGNED_TX));
|
||||||
|
|
||||||
|
assertEquals(HASH_TX, Hex.toHexString(txSigned.getHash()));
|
||||||
|
assertEquals(RLP_ENCODED_SIGNED_TX, Hex.toHexString(txSigned.getEncoded()));
|
||||||
|
|
||||||
|
assertEquals(BigInteger.ZERO, new BigInteger(1, txSigned.getNonce()));
|
||||||
|
assertEquals(new BigInteger(1, testGasPrice), new BigInteger(1, txSigned.getGasPrice()));
|
||||||
|
assertEquals(new BigInteger(1, testGasLimit), new BigInteger(1, txSigned.getGasLimit()));
|
||||||
|
assertEquals(Hex.toHexString(testReceiveAddress), Hex.toHexString(txSigned.getReceiveAddress()));
|
||||||
|
assertEquals(new BigInteger(1, testValue), new BigInteger(1, txSigned.getValue()));
|
||||||
|
assertNull(txSigned.getData());
|
||||||
|
assertEquals(27, txSigned.getSignature().v);
|
||||||
|
assertEquals("eab47c1a49bf2fe5d40e01d313900e19ca485867d462fe06e139e3a536c6d4f4", Hex.toHexString(BigIntegers.asUnsignedByteArray(txSigned.getSignature().r)));
|
||||||
|
assertEquals("14a569d327dcda4b29f74f93c0e9729d2f49ad726e703f9cd90dbb0fbf6649f1", Hex.toHexString(BigIntegers.asUnsignedByteArray(txSigned.getSignature().s)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTransactionFromUnsignedRLP() throws Exception {
|
||||||
|
Transaction txUnsigned = new Transaction(Hex.decode(RLP_ENCODED_UNSIGNED_TX));
|
||||||
|
|
||||||
|
assertEquals(HASH_TX, Hex.toHexString(txUnsigned.getHash()));
|
||||||
|
assertEquals(RLP_ENCODED_UNSIGNED_TX, Hex.toHexString(txUnsigned.getEncoded()));
|
||||||
|
txUnsigned.sign(Hex.decode(KEY));
|
||||||
|
assertEquals(RLP_ENCODED_SIGNED_TX, Hex.toHexString(txUnsigned.getEncoded()));
|
||||||
|
|
||||||
|
assertEquals(BigInteger.ZERO, new BigInteger(1, txUnsigned.getNonce()));
|
||||||
|
assertEquals(new BigInteger(1, testGasPrice), new BigInteger(1, txUnsigned.getGasPrice()));
|
||||||
|
assertEquals(new BigInteger(1, testGasLimit), new BigInteger(1, txUnsigned.getGasLimit()));
|
||||||
|
assertEquals(Hex.toHexString(testReceiveAddress), Hex.toHexString(txUnsigned.getReceiveAddress()));
|
||||||
|
assertEquals(new BigInteger(1, testValue), new BigInteger(1, txUnsigned.getValue()));
|
||||||
|
assertNull(txUnsigned.getData());
|
||||||
|
assertEquals(27, txUnsigned.getSignature().v);
|
||||||
|
assertEquals("eab47c1a49bf2fe5d40e01d313900e19ca485867d462fe06e139e3a536c6d4f4", Hex.toHexString(BigIntegers.asUnsignedByteArray(txUnsigned.getSignature().r)));
|
||||||
|
assertEquals("14a569d327dcda4b29f74f93c0e9729d2f49ad726e703f9cd90dbb0fbf6649f1", Hex.toHexString(BigIntegers.asUnsignedByteArray(txUnsigned.getSignature().s)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTransactionFromNew1() throws MissingPrivateKeyException {
|
||||||
|
Transaction txNew = new Transaction(testNonce, testGasPrice, testGasLimit, testReceiveAddress, testValue, testData);
|
||||||
|
|
||||||
|
assertEquals("", Hex.toHexString(txNew.getNonce()));
|
||||||
|
assertEquals(new BigInteger(1, testGasPrice), new BigInteger(1, txNew.getGasPrice()));
|
||||||
|
assertEquals(new BigInteger(1, testGasLimit), new BigInteger(1, txNew.getGasLimit()));
|
||||||
|
assertEquals(Hex.toHexString(testReceiveAddress), Hex.toHexString(txNew.getReceiveAddress()));
|
||||||
|
assertEquals(new BigInteger(1, testValue), new BigInteger(1, txNew.getValue()));
|
||||||
|
assertEquals("", Hex.toHexString(txNew.getData()));
|
||||||
|
assertNull(txNew.getSignature());
|
||||||
|
|
||||||
|
assertEquals(RLP_ENCODED_RAW_TX, Hex.toHexString(txNew.getEncodedRaw()));
|
||||||
|
assertEquals(HASH_TX, Hex.toHexString(txNew.getHash()));
|
||||||
|
assertEquals(RLP_ENCODED_UNSIGNED_TX, Hex.toHexString(txNew.getEncoded()));
|
||||||
|
txNew.sign(Hex.decode(KEY));
|
||||||
|
assertEquals(RLP_ENCODED_SIGNED_TX, Hex.toHexString(txNew.getEncoded()));
|
||||||
|
|
||||||
|
assertEquals(27, txNew.getSignature().v);
|
||||||
|
assertEquals("eab47c1a49bf2fe5d40e01d313900e19ca485867d462fe06e139e3a536c6d4f4", Hex.toHexString(BigIntegers.asUnsignedByteArray(txNew.getSignature().r)));
|
||||||
|
assertEquals("14a569d327dcda4b29f74f93c0e9729d2f49ad726e703f9cd90dbb0fbf6649f1", Hex.toHexString(BigIntegers.asUnsignedByteArray(txNew.getSignature().s)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTransactionFromNew2() throws MissingPrivateKeyException {
|
||||||
|
byte[] privKeyBytes = Hex.decode("c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4");
|
||||||
|
|
||||||
|
String RLP_TX_UNSIGNED = "eb8085e8d4a510008227109413978aee95f38490e9769c39b2773ed763d9cd5f872386f26fc1000080808080";
|
||||||
|
String RLP_TX_SIGNED = "f86b8085e8d4a510008227109413978aee95f38490e9769c39b2773ed763d9cd5f872386f26fc10000801ba0eab47c1a49bf2fe5d40e01d313900e19ca485867d462fe06e139e3a536c6d4f4a014a569d327dcda4b29f74f93c0e9729d2f49ad726e703f9cd90dbb0fbf6649f1";
|
||||||
|
String HASH_TX_UNSIGNED = "328ea6d24659dec48adea1aced9a136e5ebdf40258db30d1b1d97ed2b74be34e";
|
||||||
|
|
||||||
|
byte[] nonce = BigIntegers.asUnsignedByteArray(BigInteger.ZERO);
|
||||||
|
byte[] gasPrice = Hex.decode("e8d4a51000"); // 1000000000000
|
||||||
|
byte[] gas = Hex.decode("2710"); // 10000
|
||||||
|
byte[] recieveAddress = Hex.decode("13978aee95f38490e9769c39b2773ed763d9cd5f");
|
||||||
|
byte[] value = Hex.decode("2386f26fc10000"); //10000000000000000"
|
||||||
|
byte[] data = new byte[0];
|
||||||
|
|
||||||
|
Transaction tx = new Transaction(nonce, gasPrice, gas, recieveAddress, value, data);
|
||||||
|
|
||||||
|
// Testing unsigned
|
||||||
|
String encodedUnsigned = Hex.toHexString(tx.getEncoded());
|
||||||
|
assertEquals(RLP_TX_UNSIGNED, encodedUnsigned);
|
||||||
|
assertEquals(HASH_TX_UNSIGNED, Hex.toHexString(tx.getHash()));
|
||||||
|
|
||||||
|
// Testing signed
|
||||||
|
tx.sign(privKeyBytes);
|
||||||
|
String encodedSigned = Hex.toHexString(tx.getEncoded());
|
||||||
|
assertEquals(RLP_TX_SIGNED, encodedSigned);
|
||||||
|
assertEquals(HASH_TX_UNSIGNED, Hex.toHexString(tx.getHash()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTransactionCreateContract() {
|
||||||
|
|
||||||
|
// String rlp =
|
||||||
|
// "f89f808609184e72a0008203e8808203e8b84b4560005444602054600f60056002600a02010b0d630000001d596002602054630000003b5860066000530860056006600202010a0d6300000036596004604054630000003b5860056060541ca0ddc901d83110ea50bc40803f42083afea1bbd420548f6392a679af8e24b21345a06620b3b512bea5f0a272703e8d6933177c23afc79516fd0ca4a204aa6e34c7e9";
|
||||||
|
|
||||||
|
byte[] senderPrivKey = HashUtil.sha3("cow".getBytes());
|
||||||
|
|
||||||
|
byte[] nonce = BigIntegers.asUnsignedByteArray(BigInteger.ZERO);
|
||||||
|
byte[] gasPrice = Hex.decode("09184e72a000"); // 10000000000000
|
||||||
|
byte[] gas = Hex.decode("03e8"); // 1000
|
||||||
|
byte[] recieveAddress = null;
|
||||||
|
byte[] endowment = Hex.decode("03e8"); //10000000000000000"
|
||||||
|
byte[] init = Hex.decode
|
||||||
|
("4560005444602054600f60056002600a02010b0d630000001d596002602054630000003b5860066000530860056006600202010a0d6300000036596004604054630000003b586005606054");
|
||||||
|
|
||||||
|
|
||||||
|
Transaction tx1 = new Transaction(nonce, gasPrice, gas,
|
||||||
|
recieveAddress, endowment, init);
|
||||||
|
tx1.sign(senderPrivKey);
|
||||||
|
|
||||||
|
byte[] payload = tx1.getEncoded();
|
||||||
|
|
||||||
|
|
||||||
|
System.out.println(Hex.toHexString(payload));
|
||||||
|
Transaction tx2 = new Transaction(payload);
|
||||||
|
// tx2.getSender();
|
||||||
|
|
||||||
|
String plainTx1 = Hex.toHexString(tx1.getEncodedRaw());
|
||||||
|
String plainTx2 = Hex.toHexString(tx2.getEncodedRaw());
|
||||||
|
|
||||||
|
// Transaction tx = new Transaction(Hex.decode(rlp));
|
||||||
|
|
||||||
|
System.out.println("tx1.hash: " + Hex.toHexString(tx1.getHash()));
|
||||||
|
System.out.println("tx2.hash: " + Hex.toHexString(tx2.getHash()));
|
||||||
|
System.out.println();
|
||||||
|
System.out.println("plainTx1: " + plainTx1);
|
||||||
|
System.out.println("plainTx2: " + plainTx2);
|
||||||
|
|
||||||
|
System.out.println(Hex.toHexString(tx2.getSender()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void encodeReceiptTest() {
|
||||||
|
|
||||||
|
String data = "f90244a0f5ff3fbd159773816a7c707a9b8cb6bb778b934a8f6466c7830ed970498f4b688301e848b902000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000dbda94cd2a3d9f938e13cd947ec05abc7fe734df8dd826c083a1a1a1";
|
||||||
|
|
||||||
|
byte[] stateRoot = Hex.decode("f5ff3fbd159773816a7c707a9b8cb6bb778b934a8f6466c7830ed970498f4b68");
|
||||||
|
byte[] gasUsed = Hex.decode("01E848");
|
||||||
|
Bloom bloom = new Bloom(Hex.decode("0000000000000000800000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"));
|
||||||
|
|
||||||
|
LogInfo logInfo1 = new LogInfo(
|
||||||
|
Hex.decode("cd2a3d9f938e13cd947ec05abc7fe734df8dd826"),
|
||||||
|
null,
|
||||||
|
Hex.decode("a1a1a1")
|
||||||
|
);
|
||||||
|
|
||||||
|
List<LogInfo> logs = new ArrayList<>();
|
||||||
|
logs.add(logInfo1);
|
||||||
|
|
||||||
|
TransactionReceipt receipt = new TransactionReceipt(stateRoot, gasUsed, bloom, logs);
|
||||||
|
|
||||||
|
assertEquals(data,
|
||||||
|
Hex.toHexString(receipt.getEncoded()));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,352 @@
|
||||||
|
package org.ethereum.crypto;
|
||||||
|
|
||||||
|
import org.ethereum.util.Utils;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.spongycastle.crypto.AsymmetricCipherKeyPair;
|
||||||
|
import org.spongycastle.crypto.BufferedBlockCipher;
|
||||||
|
import org.spongycastle.crypto.KeyEncoder;
|
||||||
|
import org.spongycastle.crypto.KeyGenerationParameters;
|
||||||
|
import org.spongycastle.crypto.agreement.ECDHBasicAgreement;
|
||||||
|
import org.spongycastle.crypto.digests.SHA256Digest;
|
||||||
|
import org.spongycastle.crypto.engines.AESFastEngine;
|
||||||
|
import org.spongycastle.crypto.engines.IESEngine;
|
||||||
|
import org.spongycastle.crypto.generators.ECKeyPairGenerator;
|
||||||
|
import org.spongycastle.crypto.generators.EphemeralKeyPairGenerator;
|
||||||
|
import org.spongycastle.crypto.generators.KDF2BytesGenerator;
|
||||||
|
import org.spongycastle.crypto.macs.HMac;
|
||||||
|
import org.spongycastle.crypto.modes.SICBlockCipher;
|
||||||
|
import org.spongycastle.crypto.params.*;
|
||||||
|
import org.spongycastle.crypto.parsers.ECIESPublicKeyParser;
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
|
||||||
|
import static org.ethereum.crypto.HashUtil.sha3;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class CryptoTest {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger("test");
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test1() {
|
||||||
|
|
||||||
|
byte[] result = HashUtil.sha3("horse".getBytes());
|
||||||
|
|
||||||
|
assertEquals("c87f65ff3f271bf5dc8643484f66b200109caffe4bf98c4cb393dc35740b28c0",
|
||||||
|
Hex.toHexString(result));
|
||||||
|
|
||||||
|
result = HashUtil.sha3("cow".getBytes());
|
||||||
|
|
||||||
|
assertEquals("c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4",
|
||||||
|
Hex.toHexString(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test3() {
|
||||||
|
BigInteger privKey = new BigInteger("cd244b3015703ddf545595da06ada5516628c5feadbf49dc66049c4b370cc5d8", 16);
|
||||||
|
byte[] addr = ECKey.fromPrivate(privKey).getAddress();
|
||||||
|
assertEquals("89b44e4d3c81ede05d0f5de8d1a68f754d73d997", Hex.toHexString(addr));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test4() {
|
||||||
|
byte[] cowBytes = HashUtil.sha3("cow".getBytes());
|
||||||
|
byte[] addr = ECKey.fromPrivate(cowBytes).getAddress();
|
||||||
|
assertEquals("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826", Hex.toHexString(addr).toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test5() {
|
||||||
|
byte[] horseBytes = HashUtil.sha3("horse".getBytes());
|
||||||
|
byte[] addr = ECKey.fromPrivate(horseBytes).getAddress();
|
||||||
|
assertEquals("13978AEE95F38490E9769C39B2773ED763D9CD5F", Hex.toHexString(addr).toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test /* performance test */
|
||||||
|
public void test6() {
|
||||||
|
|
||||||
|
long firstTime = System.currentTimeMillis();
|
||||||
|
System.out.println(firstTime);
|
||||||
|
for (int i = 0; i < 1000; ++i) {
|
||||||
|
|
||||||
|
byte[] horseBytes = HashUtil.sha3("horse".getBytes());
|
||||||
|
byte[] addr = ECKey.fromPrivate(horseBytes).getAddress();
|
||||||
|
assertEquals("13978AEE95F38490E9769C39B2773ED763D9CD5F", Hex.toHexString(addr).toUpperCase());
|
||||||
|
}
|
||||||
|
long secondTime = System.currentTimeMillis();
|
||||||
|
System.out.println(secondTime);
|
||||||
|
System.out.println(secondTime - firstTime + " millisec");
|
||||||
|
// 1) result: ~52 address calculation every second
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test /* real tx hash calc */
|
||||||
|
public void test7() {
|
||||||
|
|
||||||
|
String txRaw = "F89D80809400000000000000000000000000000000000000008609184E72A000822710B3606956330C0D630000003359366000530A0D630000003359602060005301356000533557604060005301600054630000000C5884336069571CA07F6EB94576346488C6253197BDE6A7E59DDC36F2773672C849402AA9C402C3C4A06D254E662BF7450DD8D835160CBB053463FED0B53F2CDD7F3EA8731919C8E8CC";
|
||||||
|
byte[] txHashB = HashUtil.sha3(Hex.decode(txRaw));
|
||||||
|
String txHash = Hex.toHexString(txHashB);
|
||||||
|
assertEquals("4b7d9670a92bf120d5b43400543b69304a14d767cf836a7f6abff4edde092895", txHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test /* real block hash calc */
|
||||||
|
public void test8() {
|
||||||
|
|
||||||
|
String blockRaw = "F885F8818080A01DCC4DE8DEC75D7AAB85B567B6CCD41AD312451B948A7413F0A142FD40D49347940000000000000000000000000000000000000000A0BCDDD284BF396739C224DBA0411566C891C32115FEB998A3E2B4E61F3F35582AA01DCC4DE8DEC75D7AAB85B567B6CCD41AD312451B948A7413F0A142FD40D4934783800000808080C0C0";
|
||||||
|
|
||||||
|
byte[] blockHashB = HashUtil.sha3(Hex.decode(blockRaw));
|
||||||
|
String blockHash = Hex.toHexString(blockHashB);
|
||||||
|
System.out.println(blockHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test9() {
|
||||||
|
// TODO: https://tools.ietf.org/html/rfc6979#section-2.2
|
||||||
|
// TODO: https://github.com/bcgit/bc-java/blob/master/core/src/main/java/org/bouncycastle/crypto/signers/ECDSASigner.java
|
||||||
|
|
||||||
|
System.out.println(new BigInteger(Hex.decode("3913517ebd3c0c65000000")));
|
||||||
|
System.out.println(Utils.getValueShortString(new BigInteger("69000000000000000000000000")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test10() {
|
||||||
|
BigInteger privKey = new BigInteger("74ef8a796480dda87b4bc550b94c408ad386af0f65926a392136286784d63858", 16);
|
||||||
|
byte[] addr = ECKey.fromPrivate(privKey).getAddress();
|
||||||
|
assertEquals("ba73facb4f8291f09f27f90fe1213537b910065e", Hex.toHexString(addr));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test // basic encryption/decryption
|
||||||
|
public void test11() throws Throwable {
|
||||||
|
|
||||||
|
byte[] keyBytes = sha3("...".getBytes());
|
||||||
|
log.info("key: {}", Hex.toHexString(keyBytes));
|
||||||
|
byte[] ivBytes = new byte[16];
|
||||||
|
byte[] payload = Hex.decode("22400891000000000000000000000000");
|
||||||
|
|
||||||
|
KeyParameter key = new KeyParameter(keyBytes);
|
||||||
|
ParametersWithIV params = new ParametersWithIV(key, new byte[16]);
|
||||||
|
|
||||||
|
AESFastEngine engine = new AESFastEngine();
|
||||||
|
SICBlockCipher ctrEngine = new SICBlockCipher(engine);
|
||||||
|
|
||||||
|
ctrEngine.init(true, params);
|
||||||
|
|
||||||
|
byte[] cipher = new byte[16];
|
||||||
|
ctrEngine.processBlock(payload, 0, cipher, 0);
|
||||||
|
|
||||||
|
log.info("cipher: {}", Hex.toHexString(cipher));
|
||||||
|
|
||||||
|
|
||||||
|
byte[] output = new byte[cipher.length];
|
||||||
|
ctrEngine.init(false, params);
|
||||||
|
ctrEngine.processBlock(cipher, 0, output, 0);
|
||||||
|
|
||||||
|
assertEquals(Hex.toHexString(output), Hex.toHexString(payload));
|
||||||
|
log.info("original: {}", Hex.toHexString(payload));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // big packet encryption
|
||||||
|
public void test12() throws Throwable {
|
||||||
|
|
||||||
|
AESFastEngine engine = new AESFastEngine();
|
||||||
|
SICBlockCipher ctrEngine = new SICBlockCipher(engine);
|
||||||
|
|
||||||
|
byte[] keyBytes = Hex.decode("a4627abc2a3c25315bff732cb22bc128f203912dd2a840f31e66efb27a47d2b1");
|
||||||
|
byte[] ivBytes = new byte[16];
|
||||||
|
byte[] payload = Hex.decode("0109efc76519b683d543db9d0991bcde99cc9a3d14b1d0ecb8e9f1f66f31558593d746eaa112891b04ef7126e1dce17c9ac92ebf39e010f0028b8ec699f56f5d0c0d00");
|
||||||
|
byte[] cipherText = Hex.decode("f9fab4e9dd9fc3e5d0d0d16da254a2ac24df81c076e3214e2c57da80a46e6ae4752f4b547889fa692b0997d74f36bb7c047100ba71045cb72cfafcc7f9a251762cdf8f");
|
||||||
|
|
||||||
|
KeyParameter key = new KeyParameter(keyBytes);
|
||||||
|
ParametersWithIV params = new ParametersWithIV(key, ivBytes);
|
||||||
|
|
||||||
|
ctrEngine.init(true, params);
|
||||||
|
|
||||||
|
byte[] in = payload;
|
||||||
|
byte[] out = new byte[in.length];
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
while(i < in.length){
|
||||||
|
ctrEngine.processBlock(in, i, out, i);
|
||||||
|
i += engine.getBlockSize();
|
||||||
|
if (in.length - i < engine.getBlockSize())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// process left bytes
|
||||||
|
if (in.length - i > 0){
|
||||||
|
byte[] tmpBlock = new byte[16];
|
||||||
|
System.arraycopy(in, i, tmpBlock, 0, in.length - i);
|
||||||
|
ctrEngine.processBlock(tmpBlock, 0, tmpBlock, 0);
|
||||||
|
System.arraycopy(tmpBlock, 0, out, i, in.length - i);
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("cipher: {}", Hex.toHexString(out));
|
||||||
|
|
||||||
|
assertEquals(Hex.toHexString(cipherText), Hex.toHexString(out));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // cpp keys demystified
|
||||||
|
public void test13() throws Throwable {
|
||||||
|
|
||||||
|
// us.secret() a4627abc2a3c25315bff732cb22bc128f203912dd2a840f31e66efb27a47d2b1
|
||||||
|
// us.public() caa3d5086b31529bb00207eabf244a0a6c54d807d2ac0ec1f3b1bdde0dbf8130c115b1eaf62ce0f8062bcf70c0fefbc97cec79e7faffcc844a149a17fcd7bada
|
||||||
|
// us.address() 47d8cb63a7965d98b547b9f0333a654b60ffa190
|
||||||
|
|
||||||
|
|
||||||
|
ECKey key = ECKey.fromPrivate(Hex.decode("a4627abc2a3c25315bff732cb22bc128f203912dd2a840f31e66efb27a47d2b1"));
|
||||||
|
|
||||||
|
String address = Hex.toHexString(key.getAddress());
|
||||||
|
String pubkey = Hex.toHexString(key.getPubKeyPoint().getXCoord().getEncoded()) + // X cord
|
||||||
|
Hex.toHexString(key.getPubKeyPoint().getYCoord().getEncoded()); // Y cord
|
||||||
|
|
||||||
|
log.info("address: " + address);
|
||||||
|
log.info("pubkey: " + pubkey);
|
||||||
|
|
||||||
|
assertEquals("47d8cb63a7965d98b547b9f0333a654b60ffa190", address);
|
||||||
|
assertEquals("caa3d5086b31529bb00207eabf244a0a6c54d807d2ac0ec1f3b1bdde0dbf8130c115b1eaf62ce0f8062bcf70c0fefbc97cec79e7faffcc844a149a17fcd7bada", pubkey);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Test // ECIES_AES128_SHA256 + No Ephemeral Key + IV(all zeroes)
|
||||||
|
public void test14() throws Throwable{
|
||||||
|
|
||||||
|
AESFastEngine aesFastEngine = new AESFastEngine();
|
||||||
|
|
||||||
|
IESEngine iesEngine = new IESEngine(
|
||||||
|
new ECDHBasicAgreement(),
|
||||||
|
new KDF2BytesGenerator(new SHA256Digest()),
|
||||||
|
new HMac(new SHA256Digest()),
|
||||||
|
new BufferedBlockCipher(new SICBlockCipher(aesFastEngine)));
|
||||||
|
|
||||||
|
|
||||||
|
byte[] d = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
|
||||||
|
byte[] e = new byte[] { 8, 7, 6, 5, 4, 3, 2, 1 };
|
||||||
|
|
||||||
|
IESParameters p = new IESWithCipherParameters(d, e, 64, 128);
|
||||||
|
ParametersWithIV parametersWithIV = new ParametersWithIV(p, new byte[16]);
|
||||||
|
|
||||||
|
ECKeyPairGenerator eGen = new ECKeyPairGenerator();
|
||||||
|
KeyGenerationParameters gParam = new ECKeyGenerationParameters(ECKey.CURVE, new SecureRandom());
|
||||||
|
|
||||||
|
eGen.init(gParam);
|
||||||
|
|
||||||
|
|
||||||
|
AsymmetricCipherKeyPair p1 = eGen.generateKeyPair();
|
||||||
|
AsymmetricCipherKeyPair p2 = eGen.generateKeyPair();
|
||||||
|
|
||||||
|
|
||||||
|
ECKeyGenerationParameters keygenParams = new ECKeyGenerationParameters(ECKey.CURVE, new SecureRandom());
|
||||||
|
ECKeyPairGenerator generator = new ECKeyPairGenerator();
|
||||||
|
generator.init(keygenParams);
|
||||||
|
|
||||||
|
ECKeyPairGenerator gen = new ECKeyPairGenerator();
|
||||||
|
gen.init(new ECKeyGenerationParameters(ECKey.CURVE, new SecureRandom()));
|
||||||
|
|
||||||
|
iesEngine.init(true, p1.getPrivate(), p2.getPublic(), parametersWithIV);
|
||||||
|
|
||||||
|
byte[] message = Hex.decode("010101");
|
||||||
|
log.info("payload: {}", Hex.toHexString(message));
|
||||||
|
|
||||||
|
|
||||||
|
byte[] cipher = iesEngine.processBlock(message, 0, message.length);
|
||||||
|
log.info("cipher: {}", Hex.toHexString(cipher));
|
||||||
|
|
||||||
|
|
||||||
|
IESEngine decryptorIES_Engine = new IESEngine(
|
||||||
|
new ECDHBasicAgreement(),
|
||||||
|
new KDF2BytesGenerator (new SHA256Digest()),
|
||||||
|
new HMac(new SHA256Digest()),
|
||||||
|
new BufferedBlockCipher(new SICBlockCipher(aesFastEngine)));
|
||||||
|
|
||||||
|
decryptorIES_Engine.init(false, p2.getPrivate(), p1.getPublic(), parametersWithIV);
|
||||||
|
|
||||||
|
byte[] orig = decryptorIES_Engine.processBlock(cipher, 0, cipher.length);
|
||||||
|
|
||||||
|
log.info("orig: " + Hex.toHexString(orig));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test // ECIES_AES128_SHA256 + Ephemeral Key + IV(all zeroes)
|
||||||
|
public void test15() throws Throwable{
|
||||||
|
|
||||||
|
|
||||||
|
byte[] privKey = Hex.decode("a4627abc2a3c25315bff732cb22bc128f203912dd2a840f31e66efb27a47d2b1");
|
||||||
|
|
||||||
|
ECKey ecKey = ECKey.fromPrivate(privKey);
|
||||||
|
|
||||||
|
ECPrivateKeyParameters ecPrivKey = new ECPrivateKeyParameters(ecKey.getPrivKey(), ECKey.CURVE);
|
||||||
|
ECPublicKeyParameters ecPubKey = new ECPublicKeyParameters(ecKey.getPubKeyPoint(), ECKey.CURVE);
|
||||||
|
|
||||||
|
AsymmetricCipherKeyPair myKey = new AsymmetricCipherKeyPair(ecPubKey, ecPrivKey);
|
||||||
|
|
||||||
|
|
||||||
|
AESFastEngine aesFastEngine = new AESFastEngine();
|
||||||
|
|
||||||
|
IESEngine iesEngine = new IESEngine(
|
||||||
|
new ECDHBasicAgreement(),
|
||||||
|
new KDF2BytesGenerator(new SHA256Digest()),
|
||||||
|
new HMac(new SHA256Digest()),
|
||||||
|
new BufferedBlockCipher(new SICBlockCipher(aesFastEngine)));
|
||||||
|
|
||||||
|
|
||||||
|
byte[] d = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
|
||||||
|
byte[] e = new byte[] { 8, 7, 6, 5, 4, 3, 2, 1 };
|
||||||
|
|
||||||
|
IESParameters p = new IESWithCipherParameters(d, e, 64, 128);
|
||||||
|
ParametersWithIV parametersWithIV = new ParametersWithIV(p, new byte[16]);
|
||||||
|
|
||||||
|
ECKeyPairGenerator eGen = new ECKeyPairGenerator();
|
||||||
|
KeyGenerationParameters gParam = new ECKeyGenerationParameters(ECKey.CURVE, new SecureRandom());
|
||||||
|
|
||||||
|
eGen.init(gParam);
|
||||||
|
|
||||||
|
ECKeyGenerationParameters keygenParams = new ECKeyGenerationParameters(ECKey.CURVE, new SecureRandom());
|
||||||
|
ECKeyPairGenerator generator = new ECKeyPairGenerator();
|
||||||
|
generator.init(keygenParams);
|
||||||
|
|
||||||
|
EphemeralKeyPairGenerator kGen = new EphemeralKeyPairGenerator(generator, new KeyEncoder()
|
||||||
|
{
|
||||||
|
public byte[] getEncoded(AsymmetricKeyParameter keyParameter)
|
||||||
|
{
|
||||||
|
return ((ECPublicKeyParameters)keyParameter).getQ().getEncoded();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
ECKeyPairGenerator gen = new ECKeyPairGenerator();
|
||||||
|
gen.init(new ECKeyGenerationParameters(ECKey.CURVE, new SecureRandom()));
|
||||||
|
|
||||||
|
iesEngine.init(myKey.getPublic(), parametersWithIV, kGen);
|
||||||
|
|
||||||
|
byte[] message = Hex.decode("010101");
|
||||||
|
log.info("payload: {}", Hex.toHexString(message));
|
||||||
|
|
||||||
|
|
||||||
|
byte[] cipher = iesEngine.processBlock(message, 0, message.length);
|
||||||
|
log.info("cipher: {}", Hex.toHexString(cipher));
|
||||||
|
|
||||||
|
|
||||||
|
IESEngine decryptorIES_Engine = new IESEngine(
|
||||||
|
new ECDHBasicAgreement(),
|
||||||
|
new KDF2BytesGenerator (new SHA256Digest()),
|
||||||
|
new HMac(new SHA256Digest()),
|
||||||
|
new BufferedBlockCipher(new SICBlockCipher(aesFastEngine)));
|
||||||
|
|
||||||
|
decryptorIES_Engine.init(myKey.getPrivate(), parametersWithIV, new ECIESPublicKeyParser(ECKey.CURVE));
|
||||||
|
|
||||||
|
byte[] orig = decryptorIES_Engine.processBlock(cipher, 0, cipher.length);
|
||||||
|
|
||||||
|
log.info("orig: " + Hex.toHexString(orig));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
package org.ethereum.crypto;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.spongycastle.math.ec.ECPoint;
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
public class ECIESCoderTest {
|
||||||
|
|
||||||
|
|
||||||
|
@Test // decrypt cpp data
|
||||||
|
public void test1(){
|
||||||
|
BigInteger privKey = new BigInteger("5e173f6ac3c669587538e7727cf19b782a4f2fda07c1eaa662c593e5e85e3051", 16);
|
||||||
|
byte[] cipher = Hex.decode("049934a7b2d7f9af8fd9db941d9da281ac9381b5740e1f64f7092f3588d4f87f5ce55191a6653e5e80c1c5dd538169aa123e70dc6ffc5af1827e546c0e958e42dad355bcc1fcb9cdf2cf47ff524d2ad98cbf275e661bf4cf00960e74b5956b799771334f426df007350b46049adb21a6e78ab1408d5e6ccde6fb5e69f0f4c92bb9c725c02f99fa72b9cdc8dd53cff089e0e73317f61cc5abf6152513cb7d833f09d2851603919bf0fbe44d79a09245c6e8338eb502083dc84b846f2fee1cc310d2cc8b1b9334728f97220bb799376233e113");
|
||||||
|
|
||||||
|
byte[] payload = new byte[0];
|
||||||
|
try {
|
||||||
|
payload = ECIESCoder.decrypt(privKey, cipher);
|
||||||
|
} catch (Throwable e) {e.printStackTrace();}
|
||||||
|
|
||||||
|
Assert.assertEquals("802b052f8b066640bba94a4fc39d63815c377fced6fcb84d27f791c9921ddf3e9bf0108e298f490812847109cbd778fae393e80323fd643209841a3b7f110397f37ec61d84cea03dcc5e8385db93248584e8af4b4d1c832d8c7453c0089687a700",
|
||||||
|
Hex.toHexString(payload));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test // encrypt decrypt round trip
|
||||||
|
public void test2(){
|
||||||
|
|
||||||
|
BigInteger privKey = new BigInteger("5e173f6ac3c669587538e7727cf19b782a4f2fda07c1eaa662c593e5e85e3051", 16);
|
||||||
|
|
||||||
|
byte[] payload = Hex.decode("1122334455");
|
||||||
|
|
||||||
|
ECKey ecKey = ECKey.fromPrivate(privKey);
|
||||||
|
ECPoint pubKeyPoint = ecKey.getPubKeyPoint();
|
||||||
|
|
||||||
|
byte[] cipher = new byte[0];
|
||||||
|
try {
|
||||||
|
cipher = ECIESCoder.encrypt(pubKeyPoint, payload);
|
||||||
|
} catch (Throwable e) {e.printStackTrace();}
|
||||||
|
|
||||||
|
System.out.println(Hex.toHexString(cipher));
|
||||||
|
|
||||||
|
byte[] decrypted_payload = new byte[0];
|
||||||
|
try {
|
||||||
|
decrypted_payload = ECIESCoder.decrypt(privKey, cipher);
|
||||||
|
} catch (Throwable e) {e.printStackTrace();}
|
||||||
|
|
||||||
|
System.out.println(Hex.toHexString(decrypted_payload));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,144 @@
|
||||||
|
package org.ethereum.crypto;
|
||||||
|
|
||||||
|
import org.ethereum.ConcatKDFBytesGenerator;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.spongycastle.asn1.sec.SECNamedCurves;
|
||||||
|
import org.spongycastle.asn1.x9.X9ECParameters;
|
||||||
|
import org.spongycastle.crypto.*;
|
||||||
|
import org.spongycastle.crypto.agreement.ECDHBasicAgreement;
|
||||||
|
import org.spongycastle.crypto.digests.SHA256Digest;
|
||||||
|
import org.spongycastle.crypto.engines.AESFastEngine;
|
||||||
|
import org.spongycastle.crypto.generators.ECKeyPairGenerator;
|
||||||
|
import org.spongycastle.crypto.macs.HMac;
|
||||||
|
import org.spongycastle.crypto.modes.SICBlockCipher;
|
||||||
|
import org.spongycastle.crypto.params.*;
|
||||||
|
import org.spongycastle.math.ec.ECPoint;
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
import java.security.Security;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
|
|
||||||
|
public class ECIESTest {
|
||||||
|
public static final int KEY_SIZE = 128;
|
||||||
|
static Logger log = LoggerFactory.getLogger("test");
|
||||||
|
private static ECDomainParameters curve;
|
||||||
|
private static final String CIPHERTEXT1 = "042a851331790adacf6e64fcb19d0872fcdf1285a899a12cdc897da941816b0ea6485402aaf6c2e0a5d98ae3af1b05c68b307d1e0eb7a426a46f1617ba5b94f90b606eee3b5e9d2b527a9ee52cfa377bcd118b9390ed27ffe7d48e8155004375cae209012c3e057bb13a478a64a201d79ad4ae83";
|
||||||
|
private static final X9ECParameters IES_CURVE_PARAM = SECNamedCurves.getByName("secp256r1");
|
||||||
|
private static final BigInteger PRIVATE_KEY1 = new BigInteger("51134539186617376248226283012294527978458758538121566045626095875284492680246");
|
||||||
|
|
||||||
|
private static ECPoint pub(BigInteger d) {
|
||||||
|
return curve.getG().multiply(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void beforeAll() {
|
||||||
|
if (Security.getProvider("SC") == null)
|
||||||
|
Security.insertProviderAt(new org.spongycastle.jce.provider.BouncyCastleProvider(), 1);
|
||||||
|
curve = new ECDomainParameters(IES_CURVE_PARAM.getCurve(), IES_CURVE_PARAM.getG(), IES_CURVE_PARAM.getN(), IES_CURVE_PARAM.getH());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testKDF() {
|
||||||
|
ConcatKDFBytesGenerator kdf = new ConcatKDFBytesGenerator(new SHA256Digest());
|
||||||
|
kdf.init(new KDFParameters("Hello".getBytes(), new byte[0]));
|
||||||
|
byte[] bytes = new byte[2];
|
||||||
|
kdf.generateBytes(bytes, 0, bytes.length);
|
||||||
|
assertArrayEquals(new byte[]{-66, -89}, bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDecryptTestVector() throws IOException, InvalidCipherTextException {
|
||||||
|
ECPoint pub1 = pub(PRIVATE_KEY1);
|
||||||
|
byte[] ciphertext = Hex.decode(CIPHERTEXT1);
|
||||||
|
byte[] plaintext = decrypt(PRIVATE_KEY1, ciphertext);
|
||||||
|
assertArrayEquals(new byte[]{1,1,1}, plaintext);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRoundTrip() throws InvalidCipherTextException, IOException {
|
||||||
|
ECPoint pub1 = pub(PRIVATE_KEY1);
|
||||||
|
byte[] plaintext = "Hello world".getBytes();
|
||||||
|
byte[] ciphertext = encrypt(pub1, plaintext);
|
||||||
|
byte[] plaintext1 = decrypt(PRIVATE_KEY1, ciphertext);
|
||||||
|
assertArrayEquals(plaintext, plaintext1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] decrypt(BigInteger prv, byte[] cipher) throws InvalidCipherTextException, IOException {
|
||||||
|
ByteArrayInputStream is = new ByteArrayInputStream(cipher);
|
||||||
|
byte[] ephemBytes = new byte[2*((curve.getCurve().getFieldSize()+7)/8) + 1];
|
||||||
|
is.read(ephemBytes);
|
||||||
|
ECPoint ephem = curve.getCurve().decodePoint(ephemBytes);
|
||||||
|
byte[] IV = new byte[KEY_SIZE /8];
|
||||||
|
is.read(IV);
|
||||||
|
byte[] cipherBody = new byte[is.available()];
|
||||||
|
is.read(cipherBody);
|
||||||
|
|
||||||
|
EthereumIESEngine iesEngine = makeIESEngine(false, ephem, prv, IV);
|
||||||
|
|
||||||
|
byte[] message = iesEngine.processBlock(cipherBody, 0, cipherBody.length);
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] encrypt(ECPoint toPub, byte[] plaintext) throws InvalidCipherTextException, IOException {
|
||||||
|
|
||||||
|
ECKeyPairGenerator eGen = new ECKeyPairGenerator();
|
||||||
|
SecureRandom random = new SecureRandom();
|
||||||
|
KeyGenerationParameters gParam = new ECKeyGenerationParameters(curve, random);
|
||||||
|
|
||||||
|
eGen.init(gParam);
|
||||||
|
|
||||||
|
byte[] IV = new byte[KEY_SIZE/8];
|
||||||
|
new SecureRandom().nextBytes(IV);
|
||||||
|
|
||||||
|
AsymmetricCipherKeyPair ephemPair = eGen.generateKeyPair();
|
||||||
|
BigInteger prv = ((ECPrivateKeyParameters)ephemPair.getPrivate()).getD();
|
||||||
|
ECPoint pub = ((ECPublicKeyParameters)ephemPair.getPublic()).getQ();
|
||||||
|
EthereumIESEngine iesEngine = makeIESEngine(true, toPub, prv, IV);
|
||||||
|
|
||||||
|
|
||||||
|
ECKeyGenerationParameters keygenParams = new ECKeyGenerationParameters(curve, random);
|
||||||
|
ECKeyPairGenerator generator = new ECKeyPairGenerator();
|
||||||
|
generator.init(keygenParams);
|
||||||
|
|
||||||
|
ECKeyPairGenerator gen = new ECKeyPairGenerator();
|
||||||
|
gen.init(new ECKeyGenerationParameters(ECKey.CURVE, random));
|
||||||
|
|
||||||
|
byte[] cipher = iesEngine.processBlock(plaintext, 0, plaintext.length);
|
||||||
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
|
bos.write(pub.getEncoded(false));
|
||||||
|
bos.write(IV);
|
||||||
|
bos.write(cipher);
|
||||||
|
return bos.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static EthereumIESEngine makeIESEngine(boolean isEncrypt, ECPoint pub, BigInteger prv, byte[] IV) {
|
||||||
|
AESFastEngine aesFastEngine = new AESFastEngine();
|
||||||
|
|
||||||
|
EthereumIESEngine iesEngine = new EthereumIESEngine(
|
||||||
|
new ECDHBasicAgreement(),
|
||||||
|
new ConcatKDFBytesGenerator(new SHA256Digest()),
|
||||||
|
new HMac(new SHA256Digest()),
|
||||||
|
new SHA256Digest(),
|
||||||
|
new BufferedBlockCipher(new SICBlockCipher(aesFastEngine)));
|
||||||
|
|
||||||
|
|
||||||
|
byte[] d = new byte[] {};
|
||||||
|
byte[] e = new byte[] {};
|
||||||
|
|
||||||
|
IESParameters p = new IESWithCipherParameters(d, e, KEY_SIZE, KEY_SIZE);
|
||||||
|
ParametersWithIV parametersWithIV = new ParametersWithIV(p, IV);
|
||||||
|
|
||||||
|
iesEngine.init(isEncrypt, new ECPrivateKeyParameters(prv, curve), new ECPublicKeyParameters(pub, curve), parametersWithIV);
|
||||||
|
return iesEngine;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,297 @@
|
||||||
|
package org.ethereum.crypto;
|
||||||
|
|
||||||
|
import org.ethereum.core.Transaction;
|
||||||
|
import org.ethereum.crypto.ECKey.ECDSASignature;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.util.concurrent.Futures;
|
||||||
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
import com.google.common.util.concurrent.ListeningExecutorService;
|
||||||
|
import com.google.common.util.concurrent.MoreExecutors;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
import java.security.SignatureException;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
public class ECKeyTest {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(ECKeyTest.class);
|
||||||
|
|
||||||
|
private String privString = "3ecb44df2159c26e0f995712d4f39b6f6e499b40749b1cf1246c37f9516cb6a4";
|
||||||
|
private BigInteger privateKey = new BigInteger(Hex.decode(privString));
|
||||||
|
|
||||||
|
private String pubString = "0497466f2b32bc3bb76d4741ae51cd1d8578b48d3f1e68da206d47321aec267ce78549b514e4453d74ef11b0cd5e4e4c364effddac8b51bcfc8de80682f952896f";
|
||||||
|
private String compressedPubString = "0397466f2b32bc3bb76d4741ae51cd1d8578b48d3f1e68da206d47321aec267ce7";
|
||||||
|
private byte[] pubKey = Hex.decode(pubString);
|
||||||
|
private byte[] compressedPubKey = Hex.decode(compressedPubString);
|
||||||
|
private String address = "8a40bfaa73256b60764c1bf40675a99083efb075";
|
||||||
|
|
||||||
|
private String exampleMessage = new String("This is an example of a signed message.");
|
||||||
|
private String sigBase64 = "HD5AsBr4wuH6UU9tXuSJhUvgfGayfwoY0cKT03sFUjnpQsupHznd/3mCIRfLuNHlRCVGdAyHecdyM8IVZMtc1I8=";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHashCode() {
|
||||||
|
Assert.assertEquals(1866897155, ECKey.fromPrivate(privateKey).hashCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testECKey() {
|
||||||
|
ECKey key = new ECKey();
|
||||||
|
assertTrue(key.isPubKeyCanonical());
|
||||||
|
assertNotNull(key.getPubKey());
|
||||||
|
assertNotNull(key.getPrivKeyBytes());
|
||||||
|
log.debug(Hex.toHexString(key.getPrivKeyBytes()) + " :Generated privkey");
|
||||||
|
log.debug(Hex.toHexString(key.getPubKey()) + " :Generated pubkey");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFromPrivateKey() {
|
||||||
|
ECKey key = ECKey.fromPrivate(privateKey).decompress();
|
||||||
|
assertTrue(key.isPubKeyCanonical());
|
||||||
|
assertTrue(key.hasPrivKey());
|
||||||
|
assertArrayEquals(pubKey, key.getPubKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void testPrivatePublicKeyBytesNoArg() {
|
||||||
|
new ECKey(null, null);
|
||||||
|
fail("Expecting an IllegalArgumentException for using only null-parameters");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsPubKeyOnly() {
|
||||||
|
ECKey key = ECKey.fromPublicOnly(pubKey);
|
||||||
|
assertTrue(key.isPubKeyCanonical());
|
||||||
|
assertTrue(key.isPubKeyOnly());
|
||||||
|
assertArrayEquals(key.getPubKey(), pubKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPublicKeyFromPrivate() {
|
||||||
|
byte[] pubFromPriv = ECKey.publicKeyFromPrivate(privateKey, false);
|
||||||
|
assertArrayEquals(pubKey, pubFromPriv);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPublicKeyFromPrivateCompressed() {
|
||||||
|
byte[] pubFromPriv = ECKey.publicKeyFromPrivate(privateKey, true);
|
||||||
|
assertArrayEquals(compressedPubKey, pubFromPriv);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetAddress() {
|
||||||
|
ECKey key = ECKey.fromPublicOnly(pubKey);
|
||||||
|
assertArrayEquals(Hex.decode(address), key.getAddress());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testToString() {
|
||||||
|
ECKey key = ECKey.fromPrivate(BigInteger.TEN); // An example private key.
|
||||||
|
assertEquals("pub:04a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7893aba425419bc27a3b6c7e693a24c696f794c2ed877a1593cbee53b037368d7", key.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEthereumSign() throws IOException {
|
||||||
|
// TODO: Understand why key must be decompressed for this to work
|
||||||
|
ECKey key = ECKey.fromPrivate(privateKey).decompress();
|
||||||
|
System.out.println("Secret\t: " + Hex.toHexString(key.getPrivKeyBytes()));
|
||||||
|
System.out.println("Pubkey\t: " + Hex.toHexString(key.getPubKey()));
|
||||||
|
System.out.println("Data\t: " + exampleMessage);
|
||||||
|
byte[] messageHash = HashUtil.sha3(exampleMessage.getBytes());
|
||||||
|
ECDSASignature signature = key.sign(messageHash);
|
||||||
|
String output = signature.toBase64();
|
||||||
|
System.out.println("Signtr\t: " + output + " (Base64, length: " + output.length() + ")");
|
||||||
|
assertEquals(sigBase64, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testVerifySignature1() {
|
||||||
|
ECKey key = ECKey.fromPublicOnly(pubKey);
|
||||||
|
BigInteger r = new BigInteger("28157690258821599598544026901946453245423343069728565040002908283498585537001");
|
||||||
|
BigInteger s = new BigInteger("30212485197630673222315826773656074299979444367665131281281249560925428307087");
|
||||||
|
ECDSASignature sig = ECDSASignature.fromComponents(r.toByteArray(), s.toByteArray(), (byte) 28);
|
||||||
|
key.verify(HashUtil.sha3(exampleMessage.getBytes()), sig);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testVerifySignature2() {
|
||||||
|
BigInteger r = new BigInteger("c52c114d4f5a3ba904a9b3036e5e118fe0dbb987fe3955da20f2cd8f6c21ab9c", 16);
|
||||||
|
BigInteger s = new BigInteger("6ba4c2874299a55ad947dbc98a25ee895aabf6b625c26c435e84bfd70edf2f69", 16);
|
||||||
|
ECDSASignature sig = ECDSASignature.fromComponents(r.toByteArray(), s.toByteArray(), (byte) 0x1b);
|
||||||
|
byte[] rawtx = Hex.decode("f82804881bc16d674ec8000094cd2a3d9f938e13cd947ec05abc7fe734df8dd8268609184e72a0006480");
|
||||||
|
try {
|
||||||
|
ECKey key = ECKey.signatureToKey(HashUtil.sha3(rawtx), sig.toBase64());
|
||||||
|
System.out.println("Signature public key\t: " + Hex.toHexString(key.getPubKey()));
|
||||||
|
System.out.println("Sender is\t\t: " + Hex.toHexString(key.getAddress()));
|
||||||
|
assertEquals("cd2a3d9f938e13cd947ec05abc7fe734df8dd826", Hex.toHexString(key.getAddress()));
|
||||||
|
key.verify(HashUtil.sha3(rawtx), sig);
|
||||||
|
} catch (SignatureException e) {
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testVerifySignature3() throws SignatureException {
|
||||||
|
|
||||||
|
byte[] rawtx = Hex.decode("f86e80893635c9adc5dea000008609184e72a00082109f9479b08ad8787060333663d19704909ee7b1903e58801ba0899b92d0c76cbf18df24394996beef19c050baa9823b4a9828cd9b260c97112ea0c9e62eb4cf0a9d95ca35c8830afac567619d6b3ebee841a3c8be61d35acd8049");
|
||||||
|
|
||||||
|
Transaction tx = new Transaction(rawtx);
|
||||||
|
ECKey key = ECKey.signatureToKey(HashUtil.sha3(rawtx), tx.getSignature().toBase64());
|
||||||
|
|
||||||
|
System.out.println("Signature public key\t: " + Hex.toHexString(key.getPubKey()));
|
||||||
|
System.out.println("Sender is\t\t: " + Hex.toHexString(key.getAddress()));
|
||||||
|
|
||||||
|
// sender: CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826
|
||||||
|
// todo: add test assertion when the sign/verify part actually works.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSValue() throws Exception {
|
||||||
|
// Check that we never generate an S value that is larger than half the curve order. This avoids a malleability
|
||||||
|
// issue that can allow someone to change a transaction [hash] without invalidating the signature.
|
||||||
|
final int ITERATIONS = 10;
|
||||||
|
ListeningExecutorService executor = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(ITERATIONS));
|
||||||
|
List<ListenableFuture<ECKey.ECDSASignature>> sigFutures = Lists.newArrayList();
|
||||||
|
final ECKey key = new ECKey();
|
||||||
|
for (byte i = 0; i < ITERATIONS; i++) {
|
||||||
|
final byte[] hash = HashUtil.sha3(new byte[]{i});
|
||||||
|
sigFutures.add(executor.submit(new Callable<ECDSASignature>() {
|
||||||
|
@Override
|
||||||
|
public ECKey.ECDSASignature call() throws Exception {
|
||||||
|
return key.doSign(hash);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
List<ECKey.ECDSASignature> sigs = Futures.allAsList(sigFutures).get();
|
||||||
|
for (ECKey.ECDSASignature signature : sigs) {
|
||||||
|
assertTrue(signature.s.compareTo(ECKey.HALF_CURVE_ORDER) <= 0);
|
||||||
|
}
|
||||||
|
final ECKey.ECDSASignature duplicate = new ECKey.ECDSASignature(sigs.get(0).r, sigs.get(0).s);
|
||||||
|
assertEquals(sigs.get(0), duplicate);
|
||||||
|
assertEquals(sigs.get(0).hashCode(), duplicate.hashCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSignVerify() {
|
||||||
|
ECKey key = ECKey.fromPrivate(privateKey);
|
||||||
|
String message = new String("This is an example of a signed message.");
|
||||||
|
ECDSASignature output = key.doSign(message.getBytes());
|
||||||
|
assertTrue(key.verify(message.getBytes(), output));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsPubKeyCanonicalCorect() {
|
||||||
|
// Test correct prefix 4, right length 65
|
||||||
|
byte[] canonicalPubkey1 = new byte[65];
|
||||||
|
canonicalPubkey1[0] = 0x04;
|
||||||
|
assertTrue(ECKey.isPubKeyCanonical(canonicalPubkey1));
|
||||||
|
// Test correct prefix 2, right length 33
|
||||||
|
byte[] canonicalPubkey2 = new byte[33];
|
||||||
|
canonicalPubkey2[0] = 0x02;
|
||||||
|
assertTrue(ECKey.isPubKeyCanonical(canonicalPubkey2));
|
||||||
|
// Test correct prefix 3, right length 33
|
||||||
|
byte[] canonicalPubkey3 = new byte[33];
|
||||||
|
canonicalPubkey3[0] = 0x03;
|
||||||
|
assertTrue(ECKey.isPubKeyCanonical(canonicalPubkey3));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsPubKeyCanonicalWrongLength() {
|
||||||
|
// Test correct prefix 4, but wrong length !65
|
||||||
|
byte[] nonCanonicalPubkey1 = new byte[64];
|
||||||
|
nonCanonicalPubkey1[0] = 0x04;
|
||||||
|
assertFalse(ECKey.isPubKeyCanonical(nonCanonicalPubkey1));
|
||||||
|
// Test correct prefix 2, but wrong length !33
|
||||||
|
byte[] nonCanonicalPubkey2 = new byte[32];
|
||||||
|
nonCanonicalPubkey2[0] = 0x02;
|
||||||
|
assertFalse(ECKey.isPubKeyCanonical(nonCanonicalPubkey2));
|
||||||
|
// Test correct prefix 3, but wrong length !33
|
||||||
|
byte[] nonCanonicalPubkey3 = new byte[32];
|
||||||
|
nonCanonicalPubkey3[0] = 0x03;
|
||||||
|
assertFalse(ECKey.isPubKeyCanonical(nonCanonicalPubkey3));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsPubKeyCanonicalWrongPrefix() {
|
||||||
|
// Test wrong prefix 4, right length 65
|
||||||
|
byte[] nonCanonicalPubkey4 = new byte[65];
|
||||||
|
assertFalse(ECKey.isPubKeyCanonical(nonCanonicalPubkey4));
|
||||||
|
// Test wrong prefix 2, right length 33
|
||||||
|
byte[] nonCanonicalPubkey5 = new byte[33];
|
||||||
|
assertFalse(ECKey.isPubKeyCanonical(nonCanonicalPubkey5));
|
||||||
|
// Test wrong prefix 3, right length 33
|
||||||
|
byte[] nonCanonicalPubkey6 = new byte[33];
|
||||||
|
assertFalse(ECKey.isPubKeyCanonical(nonCanonicalPubkey6));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void keyRecovery() throws Exception {
|
||||||
|
ECKey key = new ECKey();
|
||||||
|
String message = "Hello World!";
|
||||||
|
byte[] hash = HashUtil.sha256(message.getBytes());
|
||||||
|
ECKey.ECDSASignature sig = key.doSign(hash);
|
||||||
|
key = ECKey.fromPublicOnly(key.getPubKeyPoint());
|
||||||
|
boolean found = false;
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
ECKey key2 = ECKey.recoverFromSignature(i, sig, hash, true);
|
||||||
|
checkNotNull(key2);
|
||||||
|
if (key.equals(key2)) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertTrue(found);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSignedMessageToKey() throws SignatureException {
|
||||||
|
byte[] messageHash = HashUtil.sha3(exampleMessage.getBytes());
|
||||||
|
ECKey key = ECKey.signatureToKey(messageHash, sigBase64);
|
||||||
|
assertNotNull(key);
|
||||||
|
assertArrayEquals(pubKey, key.getPubKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetPrivKeyBytes() {
|
||||||
|
ECKey key = new ECKey();
|
||||||
|
assertNotNull(key.getPrivKeyBytes());
|
||||||
|
assertEquals(32, key.getPrivKeyBytes().length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEqualsObject() {
|
||||||
|
ECKey key0 = new ECKey();
|
||||||
|
ECKey key1 = ECKey.fromPrivate(privateKey);
|
||||||
|
ECKey key2 = ECKey.fromPrivate(privateKey);
|
||||||
|
|
||||||
|
assertFalse(key0.equals(key1));
|
||||||
|
assertTrue(key1.equals(key1));
|
||||||
|
assertTrue(key1.equals(key2));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void decryptAECSIC(){
|
||||||
|
ECKey key = ECKey.fromPrivate(Hex.decode("abb51256c1324a1350598653f46aa3ad693ac3cf5d05f36eba3f495a1f51590f"));
|
||||||
|
byte[] payload = key.decryptAES(Hex.decode("84a727bc81fa4b13947dc9728b88fd08"));
|
||||||
|
System.out.println(Hex.toHexString(payload));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
package org.ethereum.datasource;
|
||||||
|
|
||||||
|
import org.ethereum.config.SystemProperties;
|
||||||
|
import org.ethereum.datasource.redis.RedisConnection;
|
||||||
|
import org.ethereum.db.BlockStore;
|
||||||
|
import org.ethereum.db.InMemoryBlockStore;
|
||||||
|
import org.ethereum.manager.WorldManager;
|
||||||
|
import org.hibernate.SessionFactory;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
import org.springframework.test.context.support.AnnotationConfigContextLoader;
|
||||||
|
import org.springframework.transaction.annotation.Propagation;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import redis.clients.jedis.Jedis;
|
||||||
|
import org.ethereum.TestContext;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
|
||||||
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
|
@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
|
||||||
|
public abstract class AbstractRedisTest {
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@ComponentScan(basePackages = "org.ethereum")
|
||||||
|
static class ContextConfiguration extends TestContext {
|
||||||
|
static {
|
||||||
|
SystemProperties.CONFIG.setDataBaseDir("test_db/" + "RedisAll");
|
||||||
|
SystemProperties.CONFIG.setDatabaseReset(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@Transactional(propagation = Propagation.SUPPORTS)
|
||||||
|
public BlockStore blockStore(SessionFactory sessionFactory){
|
||||||
|
return new InMemoryBlockStore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RedisConnection redisConnection;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
WorldManager worldManager;
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void close(){
|
||||||
|
worldManager.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Boolean connected;
|
||||||
|
|
||||||
|
protected RedisConnection getRedisConnection() {
|
||||||
|
return redisConnection;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Boolean isConnected() {
|
||||||
|
if (connected == null) {
|
||||||
|
String url = System.getenv(RedisConnection.REDISCLOUD_URL);
|
||||||
|
try {
|
||||||
|
Jedis jedis = new Jedis(new URI(url));
|
||||||
|
connected = jedis.ping().equals("PONG");
|
||||||
|
jedis.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
connected = false;
|
||||||
|
System.out.printf("Cannot connect to '%s' Redis cloud.\n", url);
|
||||||
|
}
|
||||||
|
|
||||||
|
assertFalse(connected ^ redisConnection.isAvailable());
|
||||||
|
}
|
||||||
|
|
||||||
|
return connected;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
package org.ethereum.datasource;
|
||||||
|
|
||||||
|
import org.ethereum.datasource.redis.RedisDataSource;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Roman Mandeleil
|
||||||
|
*/
|
||||||
|
public class RedisDataSourceTest extends AbstractRedisTest {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSet1() {
|
||||||
|
if (!isConnected()) return;
|
||||||
|
|
||||||
|
KeyValueDataSource dataSource = createDataSource("test-state");
|
||||||
|
try {
|
||||||
|
byte[] key = Hex.decode("a1a2a3");
|
||||||
|
byte[] val = Hex.decode("b1b2b3");
|
||||||
|
|
||||||
|
dataSource.put(key, val);
|
||||||
|
byte[] val2 = dataSource.get(key);
|
||||||
|
|
||||||
|
Assert.assertEquals(Hex.toHexString(val), Hex.toHexString(val2));
|
||||||
|
} finally {
|
||||||
|
clear(dataSource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSet2() {
|
||||||
|
if (!isConnected()) return;
|
||||||
|
|
||||||
|
KeyValueDataSource states = createDataSource("test-state");
|
||||||
|
KeyValueDataSource details = createDataSource("test-details");
|
||||||
|
|
||||||
|
try {
|
||||||
|
byte[] key = Hex.decode("a1a2a3");
|
||||||
|
byte[] val1 = Hex.decode("b1b2b3");
|
||||||
|
byte[] val2 = Hex.decode("c1c2c3");
|
||||||
|
|
||||||
|
states.put(key, val1);
|
||||||
|
details.put(key, val2);
|
||||||
|
|
||||||
|
byte[] res1 = states.get(key);
|
||||||
|
byte[] res2 = details.get(key);
|
||||||
|
|
||||||
|
Assert.assertEquals(Hex.toHexString(val1), Hex.toHexString(res1));
|
||||||
|
Assert.assertEquals(Hex.toHexString(val2), Hex.toHexString(res2));
|
||||||
|
} finally {
|
||||||
|
clear(states);
|
||||||
|
clear(details);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private KeyValueDataSource createDataSource(String name) {
|
||||||
|
KeyValueDataSource result = getRedisConnection().createDataSource(name);
|
||||||
|
result.setName(name);
|
||||||
|
result.init();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clear(KeyValueDataSource dataSource) {
|
||||||
|
((RedisDataSource) dataSource).clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,130 @@
|
||||||
|
package org.ethereum.datasource;
|
||||||
|
|
||||||
|
import org.ethereum.core.Transaction;
|
||||||
|
import org.ethereum.crypto.ECKey;
|
||||||
|
import org.ethereum.crypto.HashUtil;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static java.util.Arrays.asList;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
public class RedisStorageTest extends AbstractRedisTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRedisSet() {
|
||||||
|
if (!isConnected()) return;
|
||||||
|
|
||||||
|
Pojo elephant = Pojo.create(5L, "elephant");
|
||||||
|
Pojo lion = Pojo.create(5L, "lion");
|
||||||
|
|
||||||
|
Set<Pojo> ranch = getRedisConnection().createSetFor(Pojo.class, "ranch");
|
||||||
|
Pojo chicken = Pojo.create(1L, "chicken");
|
||||||
|
Pojo cow = Pojo.create(2L, "cow");
|
||||||
|
Pojo puppy = Pojo.create(3L, "puppy");
|
||||||
|
Pojo kitten = Pojo.create(4L, "kitten");
|
||||||
|
|
||||||
|
assertTrue(ranch.add(chicken));
|
||||||
|
assertFalse(ranch.add(chicken));
|
||||||
|
assertTrue(ranch.contains(chicken));
|
||||||
|
assertEquals(1, ranch.size());
|
||||||
|
|
||||||
|
Pojo next = ranch.iterator().next();
|
||||||
|
assertNotNull(next);
|
||||||
|
assertEquals(chicken, next);
|
||||||
|
|
||||||
|
assertTrue(ranch.addAll(asList(cow, puppy, kitten)));
|
||||||
|
assertEquals(4, ranch.size());
|
||||||
|
assertFalse(ranch.isEmpty());
|
||||||
|
assertFalse(ranch.remove(elephant));
|
||||||
|
assertFalse(ranch.removeAll(asList(cow, lion, elephant)));
|
||||||
|
assertEquals(3, ranch.size());
|
||||||
|
|
||||||
|
assertTrue(ranch.retainAll(asList(kitten, puppy)));
|
||||||
|
assertEquals(2, ranch.size());
|
||||||
|
|
||||||
|
ranch.clear();
|
||||||
|
assertEquals(0, ranch.size());
|
||||||
|
assertTrue(ranch.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSeveralSetsWithOneName() {
|
||||||
|
if (!isConnected()) return;
|
||||||
|
|
||||||
|
final String name = "testTransactions";
|
||||||
|
Set<Transaction> transactions = getRedisConnection().createTransactionSet(name);
|
||||||
|
transactions.add(createTransaction("09184e72a000", "4255", "1000000000000000000000", "cat"));
|
||||||
|
transactions.add(createTransaction("09184e72a000", "4255", "1000000000000000000000", "dog"));
|
||||||
|
transactions.add(createTransaction("09184e72a000", "4255", "1000000000000000000000", "rabbit"));
|
||||||
|
|
||||||
|
Set<Transaction> transactions1 = getRedisConnection().createTransactionSet(name);
|
||||||
|
transactions1.add(createTransaction("09184e72a000", "4255", "1000000000000000000000", "duck"));
|
||||||
|
transactions1.add(createTransaction("09184e72a000", "4255", "1000000000000000000000", "chicken"));
|
||||||
|
transactions1.add(createTransaction("09184e72a000", "4255", "1000000000000000000000", "cow"));
|
||||||
|
|
||||||
|
assertEquals(6, transactions1.size());
|
||||||
|
transactions.clear();
|
||||||
|
assertTrue(transactions1.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Pojo {
|
||||||
|
private Long id;
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Pojo create(long id, String name) {
|
||||||
|
Pojo result = new Pojo();
|
||||||
|
result.setId(id);
|
||||||
|
result.setName(name);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj == null || !getClass().isInstance(obj)) return false;
|
||||||
|
if (this == obj) return true;
|
||||||
|
|
||||||
|
Pojo another = (Pojo) obj;
|
||||||
|
return (another.getId() == getId()) && another.getName().equals(getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int hashCode = 17;
|
||||||
|
|
||||||
|
hashCode += ((getId() == null) ? 0 : getId().hashCode()) * 31;
|
||||||
|
hashCode += ((getName() == null) ? 0 : getName().hashCode()) * 31;
|
||||||
|
|
||||||
|
return hashCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Transaction createTransaction(String gasPrice, String gas, String val, String secret) {
|
||||||
|
|
||||||
|
ECKey ecKey = ECKey.fromPrivate(HashUtil.sha3(secret.getBytes()));
|
||||||
|
|
||||||
|
// Tn (nonce); Tp(pgas); Tg(gaslimi); Tt(value); Tv(value); Ti(sender); Tw; Tr; Ts
|
||||||
|
return new Transaction(null, Hex.decode(gasPrice), Hex.decode(gas), ecKey.getAddress(),
|
||||||
|
new BigInteger(val).toByteArray(),
|
||||||
|
null);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,143 @@
|
||||||
|
package org.ethereum.db;
|
||||||
|
|
||||||
|
import org.ethereum.util.FastByteComparisons;
|
||||||
|
|
||||||
|
import com.google.common.primitives.UnsignedBytes;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
public class ByteArrayWrapperTest {
|
||||||
|
|
||||||
|
static ByteArrayWrapper wrapper1;
|
||||||
|
static ByteArrayWrapper wrapper2;
|
||||||
|
static ByteArrayWrapper wrapper3;
|
||||||
|
static ByteArrayWrapper wrapper4;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void loadByteArrays() {
|
||||||
|
|
||||||
|
String block = "f9072df8d3a077ef4fdaf389dca53236bcf7f72698e154eab2828f86fbc4fc6c"
|
||||||
|
+ "d9225d285c89a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0"
|
||||||
|
+ "a142fd40d493479476f5eabe4b342ee56b8ceba6ab2a770c3e2198e7a0faa0ca"
|
||||||
|
+ "43105f667dceb168eb4e0cdc98ef28a9da5c381edef70d843207601719a06785"
|
||||||
|
+ "f3860460b2aa29122698e83a5151b270e82532c1663e89e3df8c5445b8ca833f"
|
||||||
|
+ "f000018609184e72a000830f3e6f8227d2845387c58f80a00000000000000000"
|
||||||
|
+ "0000000000000000000000000000000094148d7738f78c04f90654f8c6f8a080"
|
||||||
|
+ "8609184e72a00082271094000000000000000000000000000000000000000080"
|
||||||
|
+ "b83a33604557602a5160106000396000f200604556330e0f602a59366000530a"
|
||||||
|
+ "0f602a596020600053013560005335576040600053016000546009581ca033a6"
|
||||||
|
+ "bfa5eb2f4b63f1b98bed9a987d096d32e56deecb050367c84955508f5365a015"
|
||||||
|
+ "034e7574ec073f0c448aac1d9f844387610dfef5342834b6825fbc35df5913a0"
|
||||||
|
+ "ee258e73d41ada73d8d6071ba7d236fbbe24fcfb9627fbd4310e24ffd87b961a"
|
||||||
|
+ "8203e9f90194f9016d018609184e72a000822710940000000000000000000000"
|
||||||
|
+ "00000000000000000080b901067f4e616d655265670000000000000000000000"
|
||||||
|
+ "00000000000000000000000000003057307f4e616d6552656700000000000000"
|
||||||
|
+ "000000000000000000000000000000000000577f436f6e666967000000000000"
|
||||||
|
+ "000000000000000000000000000000000000000073ccdeac59d35627b7de0933"
|
||||||
|
+ "2e819d5159e7bb72505773ccdeac59d35627b7de09332e819d5159e7bb72507f"
|
||||||
|
+ "436f6e6669670000000000000000000000000000000000000000000000000000"
|
||||||
|
+ "57336045576041516100c56000396000f20036602259604556330e0f600f5933"
|
||||||
|
+ "ff33560f601e5960003356576000335700604158600035560f602b590033560f"
|
||||||
|
+ "603659600033565733600035576000353357001ca0f3c527e484ea5546189979"
|
||||||
|
+ "c767b69aa9f1ad5a6f4b6077d4bccf5142723a67c9a069a4a29a2a315102fcd0"
|
||||||
|
+ "822d39ad696a6d7988c993bb2b911cc2a78bb8902d91a01ebe4782ea3ed224cc"
|
||||||
|
+ "bb777f5de9ee7b5bbb282ac08f7fa0ef95d3d1c1c6d1a1820ef7f8ccf8a60286"
|
||||||
|
+ "09184e72a00082271094ccdeac59d35627b7de09332e819d5159e7bb725080b8"
|
||||||
|
+ "4000000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
+ "000000000000000000000000002d0aceee7e5ab874e22ccf8d1a649f59106d74"
|
||||||
|
+ "e81ba095ad45bf574c080e4d72da2cfd3dbe06cc814c1c662b5f74561f13e1e7"
|
||||||
|
+ "5058f2a057745a3db5482bccb5db462922b074f4b79244c4b1fa811ed094d728"
|
||||||
|
+ "e7b6da92a08599ea5d6cb6b9ad3311f0d82a3337125e05f4a82b9b0556cb3776"
|
||||||
|
+ "a6e1a02f8782132df8abf885038609184e72a000822710942d0aceee7e5ab874"
|
||||||
|
+ "e22ccf8d1a649f59106d74e880a0476176000000000000000000000000000000"
|
||||||
|
+ "00000000000000000000000000001ca09b5fdabd54ebc284249d2d2df6d43875"
|
||||||
|
+ "cb86c52bd2bac196d4f064c8ade054f2a07b33f5c8b277a408ec38d2457441d2"
|
||||||
|
+ "af32e55681c8ecb28eef3d2a152e8db5a9a0227a67fceb1bf4ddd31a7047e24b"
|
||||||
|
+ "e93c947ab3b539471555bb3509ed6e393c8e82178df90277f90250048609184e"
|
||||||
|
+ "72a0008246dd94000000000000000000000000000000000000000080b901e961"
|
||||||
|
+ "010033577f476176436f696e0000000000000000000000000000000000000000"
|
||||||
|
+ "000000000060005460006000600760006000732d0aceee7e5ab874e22ccf8d1a"
|
||||||
|
+ "649f59106d74e860645c03f150436000576000600157620f424060025761017d"
|
||||||
|
+ "5161006c6000396000f2006020360e0f61013f59602060006000374360205460"
|
||||||
|
+ "0056600054602056602054437f6e000000000000000000000000000000000000"
|
||||||
|
+ "00000000000000000000000000560e0f0f61008059437f6e0000000000000000"
|
||||||
|
+ "0000000000000000000000000000000000000000000000576000602054610400"
|
||||||
|
+ "60005304600053036000547f6400000000000000000000000000000000000000"
|
||||||
|
+ "0000000000000000000000005660016000030460406000200a0f61013e596001"
|
||||||
|
+ "60205301602054600a6020530b0f6100f45961040060005304600053017f6400"
|
||||||
|
+ "0000000000000000000000000000000000000000000000000000000000005760"
|
||||||
|
+ "20537f6900000000000000000000000000000000000000000000000000000000"
|
||||||
|
+ "000000576000537f640000000000000000000000000000000000000000000000"
|
||||||
|
+ "000000000000000057006040360e0f0f61014a59003356604054600035566060"
|
||||||
|
+ "546020356080546080536040530a0f6101695900608053604053033357608053"
|
||||||
|
+ "60605301600035571ba0190fc7ab634dc497fe1656fde523a4c26926d51a93db"
|
||||||
|
+ "2ba37af8e83c3741225da066ae0ec1217b0ca698a5369d4881e1c4cbde56af99"
|
||||||
|
+ "31ebf9281580a23b659c08a051f947cb2315d0259f55848c630caa10cd91d6e4"
|
||||||
|
+ "4ff8bad7758c65b25e2191308227d2c0";
|
||||||
|
|
||||||
|
byte[] test1 = Hex.decode(block);
|
||||||
|
byte[] test2 = Hex.decode(block);
|
||||||
|
byte[] test3 = Hex.decode("4ff8bad7758c65b25e2191308227d2c0");
|
||||||
|
byte[] test4 = Hex.decode("");
|
||||||
|
|
||||||
|
wrapper1 = new ByteArrayWrapper(test1);
|
||||||
|
wrapper2 = new ByteArrayWrapper(test2);
|
||||||
|
wrapper3 = new ByteArrayWrapper(test3);
|
||||||
|
wrapper4 = new ByteArrayWrapper(test4);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEqualsObject() {
|
||||||
|
assertTrue(wrapper1.equals(wrapper2));
|
||||||
|
assertFalse(wrapper1.equals(wrapper3));
|
||||||
|
assertFalse(wrapper1.equals(wrapper4));
|
||||||
|
assertFalse(wrapper1.equals(null));
|
||||||
|
assertFalse(wrapper2.equals(wrapper3));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCompareTo() {
|
||||||
|
assertTrue(wrapper1.compareTo(wrapper2) == 0);
|
||||||
|
assertTrue(wrapper1.compareTo(wrapper3) > 1);
|
||||||
|
assertTrue(wrapper1.compareTo(wrapper4) > 1);
|
||||||
|
assertTrue(wrapper2.compareTo(wrapper3) > 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEqualsPerformance() {
|
||||||
|
boolean testEnabled = false;
|
||||||
|
|
||||||
|
if (testEnabled) {
|
||||||
|
final int ITERATIONS = 10000000;
|
||||||
|
long start1 = System.currentTimeMillis();
|
||||||
|
for (int i = 0; i < ITERATIONS; i++) {
|
||||||
|
Comparator<byte[]> comparator = UnsignedBytes
|
||||||
|
.lexicographicalComparator();
|
||||||
|
|
||||||
|
comparator.compare(wrapper1.getData(),
|
||||||
|
wrapper2.getData());
|
||||||
|
}
|
||||||
|
System.out.println(System.currentTimeMillis() - start1 + "ms");
|
||||||
|
|
||||||
|
long start2 = System.currentTimeMillis();
|
||||||
|
for (int i = 0; i < ITERATIONS; i++) {
|
||||||
|
Arrays.equals(wrapper1.getData(), wrapper2.getData());
|
||||||
|
}
|
||||||
|
System.out.println(System.currentTimeMillis() - start2 + "ms");
|
||||||
|
|
||||||
|
long start3 = System.currentTimeMillis();
|
||||||
|
for (int i = 0; i < ITERATIONS; i++) {
|
||||||
|
FastByteComparisons.compareTo(wrapper1.getData(), 0, wrapper1.getData().length, wrapper2.getData(), 0, wrapper1.getData().length);
|
||||||
|
}
|
||||||
|
System.out.println(System.currentTimeMillis() - start3 + "ms");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,557 @@
|
||||||
|
package org.ethereum.db;
|
||||||
|
|
||||||
|
import org.ethereum.config.SystemProperties;
|
||||||
|
import org.ethereum.core.Genesis;
|
||||||
|
import org.ethereum.crypto.HashUtil;
|
||||||
|
|
||||||
|
import org.ethereum.datasource.LevelDbDataSource;
|
||||||
|
import org.ethereum.facade.Repository;
|
||||||
|
import org.ethereum.vm.DataWord;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.FixMethodOrder;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runners.MethodSorters;
|
||||||
|
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Roman Mandeleil
|
||||||
|
* @since 17.11.2014
|
||||||
|
*/
|
||||||
|
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||||
|
public class RepositoryTest {
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test1() {
|
||||||
|
|
||||||
|
SystemProperties.CONFIG.setDataBaseDir("test_db/" + RepositoryTest.class);
|
||||||
|
Repository repository = new RepositoryImpl(new LevelDbDataSource(), new LevelDbDataSource());
|
||||||
|
|
||||||
|
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
|
||||||
|
byte[] horse = Hex.decode("13978AEE95F38490E9769C39B2773ED763D9CD5F");
|
||||||
|
|
||||||
|
repository.increaseNonce(cow);
|
||||||
|
repository.increaseNonce(horse);
|
||||||
|
|
||||||
|
assertEquals(BigInteger.ONE, repository.getNonce(cow));
|
||||||
|
assertEquals(BigInteger.ONE, repository.getNonce(horse));
|
||||||
|
|
||||||
|
repository.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test2() {
|
||||||
|
|
||||||
|
SystemProperties.CONFIG.setDataBaseDir("test_db/" + RepositoryTest.class);
|
||||||
|
Repository repository = new RepositoryImpl(new LevelDbDataSource(), new LevelDbDataSource());
|
||||||
|
|
||||||
|
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
|
||||||
|
byte[] horse = Hex.decode("13978AEE95F38490E9769C39B2773ED763D9CD5F");
|
||||||
|
|
||||||
|
repository.addBalance(cow, BigInteger.TEN);
|
||||||
|
repository.addBalance(horse, BigInteger.ONE);
|
||||||
|
|
||||||
|
assertEquals(BigInteger.TEN, repository.getBalance(cow));
|
||||||
|
assertEquals(BigInteger.ONE, repository.getBalance(horse));
|
||||||
|
|
||||||
|
repository.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test3() {
|
||||||
|
|
||||||
|
SystemProperties.CONFIG.setDataBaseDir("test_db/" + RepositoryTest.class);
|
||||||
|
Repository repository = new RepositoryImpl(new LevelDbDataSource(), new LevelDbDataSource());
|
||||||
|
|
||||||
|
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
|
||||||
|
byte[] horse = Hex.decode("13978AEE95F38490E9769C39B2773ED763D9CD5F");
|
||||||
|
|
||||||
|
byte[] cowCode = Hex.decode("A1A2A3");
|
||||||
|
byte[] horseCode = Hex.decode("B1B2B3");
|
||||||
|
|
||||||
|
repository.saveCode(cow, cowCode);
|
||||||
|
repository.saveCode(horse, horseCode);
|
||||||
|
|
||||||
|
assertArrayEquals(cowCode, repository.getCode(cow));
|
||||||
|
assertArrayEquals(horseCode, repository.getCode(horse));
|
||||||
|
|
||||||
|
repository.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test4() {
|
||||||
|
|
||||||
|
SystemProperties.CONFIG.setDataBaseDir("test_db/" + RepositoryTest.class);
|
||||||
|
Repository repository = new RepositoryImpl(new LevelDbDataSource(), new LevelDbDataSource());
|
||||||
|
|
||||||
|
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
|
||||||
|
byte[] horse = Hex.decode("13978AEE95F38490E9769C39B2773ED763D9CD5F");
|
||||||
|
|
||||||
|
byte[] cowKey = Hex.decode("A1A2A3");
|
||||||
|
byte[] cowValue = Hex.decode("A4A5A6");
|
||||||
|
|
||||||
|
byte[] horseKey = Hex.decode("B1B2B3");
|
||||||
|
byte[] horseValue = Hex.decode("B4B5B6");
|
||||||
|
|
||||||
|
repository.addStorageRow(cow, new DataWord(cowKey), new DataWord(cowValue));
|
||||||
|
repository.addStorageRow(horse, new DataWord(horseKey), new DataWord(horseValue));
|
||||||
|
|
||||||
|
assertEquals(new DataWord(cowValue), repository.getStorageValue(cow, new DataWord(cowKey)));
|
||||||
|
assertEquals(new DataWord(horseValue), repository.getStorageValue(horse, new DataWord(horseKey)));
|
||||||
|
|
||||||
|
repository.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test5() {
|
||||||
|
|
||||||
|
SystemProperties.CONFIG.setDataBaseDir("test_db/" + RepositoryTest.class);
|
||||||
|
Repository repository = new RepositoryImpl(new LevelDbDataSource(), new LevelDbDataSource());
|
||||||
|
Repository track = repository.startTracking();
|
||||||
|
|
||||||
|
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
|
||||||
|
byte[] horse = Hex.decode("13978AEE95F38490E9769C39B2773ED763D9CD5F");
|
||||||
|
|
||||||
|
track.increaseNonce(cow);
|
||||||
|
track.increaseNonce(cow);
|
||||||
|
track.increaseNonce(cow);
|
||||||
|
track.increaseNonce(cow);
|
||||||
|
track.increaseNonce(cow);
|
||||||
|
track.increaseNonce(cow);
|
||||||
|
track.increaseNonce(cow);
|
||||||
|
track.increaseNonce(cow);
|
||||||
|
track.increaseNonce(cow);
|
||||||
|
track.increaseNonce(cow);
|
||||||
|
|
||||||
|
track.increaseNonce(horse);
|
||||||
|
|
||||||
|
track.commit();
|
||||||
|
|
||||||
|
assertEquals(BigInteger.TEN, repository.getNonce(cow));
|
||||||
|
assertEquals(BigInteger.ONE, repository.getNonce(horse));
|
||||||
|
|
||||||
|
repository.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test6() {
|
||||||
|
|
||||||
|
SystemProperties.CONFIG.setDataBaseDir("test_db/" + RepositoryTest.class);
|
||||||
|
Repository repository = new RepositoryImpl(new LevelDbDataSource(), new LevelDbDataSource());
|
||||||
|
Repository track = repository.startTracking();
|
||||||
|
|
||||||
|
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
|
||||||
|
byte[] horse = Hex.decode("13978AEE95F38490E9769C39B2773ED763D9CD5F");
|
||||||
|
|
||||||
|
track.increaseNonce(cow);
|
||||||
|
track.increaseNonce(cow);
|
||||||
|
track.increaseNonce(cow);
|
||||||
|
track.increaseNonce(cow);
|
||||||
|
track.increaseNonce(cow);
|
||||||
|
track.increaseNonce(cow);
|
||||||
|
track.increaseNonce(cow);
|
||||||
|
track.increaseNonce(cow);
|
||||||
|
track.increaseNonce(cow);
|
||||||
|
track.increaseNonce(cow);
|
||||||
|
|
||||||
|
track.increaseNonce(horse);
|
||||||
|
|
||||||
|
assertEquals(BigInteger.TEN, track.getNonce(cow));
|
||||||
|
assertEquals(BigInteger.ONE, track.getNonce(horse));
|
||||||
|
|
||||||
|
track.rollback();
|
||||||
|
|
||||||
|
assertEquals(BigInteger.ZERO, repository.getNonce(cow));
|
||||||
|
assertEquals(BigInteger.ZERO, repository.getNonce(horse));
|
||||||
|
|
||||||
|
repository.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test7() {
|
||||||
|
|
||||||
|
SystemProperties.CONFIG.setDataBaseDir("test_db/" + RepositoryTest.class);
|
||||||
|
Repository repository = new RepositoryImpl(new LevelDbDataSource(), new LevelDbDataSource());
|
||||||
|
Repository track = repository.startTracking();
|
||||||
|
|
||||||
|
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
|
||||||
|
byte[] horse = Hex.decode("13978AEE95F38490E9769C39B2773ED763D9CD5F");
|
||||||
|
|
||||||
|
track.addBalance(cow, BigInteger.TEN);
|
||||||
|
track.addBalance(horse, BigInteger.ONE);
|
||||||
|
|
||||||
|
assertEquals(BigInteger.TEN, track.getBalance(cow));
|
||||||
|
assertEquals(BigInteger.ONE, track.getBalance(horse));
|
||||||
|
|
||||||
|
track.commit();
|
||||||
|
|
||||||
|
assertEquals(BigInteger.TEN, repository.getBalance(cow));
|
||||||
|
assertEquals(BigInteger.ONE, repository.getBalance(horse));
|
||||||
|
|
||||||
|
repository.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test8() {
|
||||||
|
|
||||||
|
SystemProperties.CONFIG.setDataBaseDir("test_db/" + RepositoryTest.class);
|
||||||
|
Repository repository = new RepositoryImpl(new LevelDbDataSource(), new LevelDbDataSource());
|
||||||
|
Repository track = repository.startTracking();
|
||||||
|
|
||||||
|
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
|
||||||
|
byte[] horse = Hex.decode("13978AEE95F38490E9769C39B2773ED763D9CD5F");
|
||||||
|
|
||||||
|
track.addBalance(cow, BigInteger.TEN);
|
||||||
|
track.addBalance(horse, BigInteger.ONE);
|
||||||
|
|
||||||
|
assertEquals(BigInteger.TEN, track.getBalance(cow));
|
||||||
|
assertEquals(BigInteger.ONE, track.getBalance(horse));
|
||||||
|
|
||||||
|
track.rollback();
|
||||||
|
|
||||||
|
assertEquals(BigInteger.ZERO, repository.getBalance(cow));
|
||||||
|
assertEquals(BigInteger.ZERO, repository.getBalance(horse));
|
||||||
|
|
||||||
|
repository.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test9() {
|
||||||
|
|
||||||
|
SystemProperties.CONFIG.setDataBaseDir("test_db/" + RepositoryTest.class);
|
||||||
|
Repository repository = new RepositoryImpl(new LevelDbDataSource(), new LevelDbDataSource());
|
||||||
|
Repository track = repository.startTracking();
|
||||||
|
|
||||||
|
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
|
||||||
|
byte[] horse = Hex.decode("13978AEE95F38490E9769C39B2773ED763D9CD5F");
|
||||||
|
|
||||||
|
DataWord cowKey = new DataWord(Hex.decode("A1A2A3"));
|
||||||
|
DataWord cowValue = new DataWord(Hex.decode("A4A5A6"));
|
||||||
|
|
||||||
|
DataWord horseKey = new DataWord(Hex.decode("B1B2B3"));
|
||||||
|
DataWord horseValue = new DataWord(Hex.decode("B4B5B6"));
|
||||||
|
|
||||||
|
track.addStorageRow(cow, cowKey, cowValue);
|
||||||
|
track.addStorageRow(horse, horseKey, horseValue);
|
||||||
|
|
||||||
|
assertEquals(cowValue, track.getStorageValue(cow, cowKey));
|
||||||
|
assertEquals(horseValue, track.getStorageValue(horse, horseKey));
|
||||||
|
|
||||||
|
track.commit();
|
||||||
|
|
||||||
|
assertEquals(cowValue, repository.getStorageValue(cow, cowKey));
|
||||||
|
assertEquals(horseValue, repository.getStorageValue(horse, horseKey));
|
||||||
|
|
||||||
|
repository.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test10() {
|
||||||
|
|
||||||
|
SystemProperties.CONFIG.setDataBaseDir("test_db/" + RepositoryTest.class);
|
||||||
|
Repository repository = new RepositoryImpl(new LevelDbDataSource(), new LevelDbDataSource());
|
||||||
|
Repository track = repository.startTracking();
|
||||||
|
|
||||||
|
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
|
||||||
|
byte[] horse = Hex.decode("13978AEE95F38490E9769C39B2773ED763D9CD5F");
|
||||||
|
|
||||||
|
DataWord cowKey = new DataWord(Hex.decode("A1A2A3"));
|
||||||
|
DataWord cowValue = new DataWord(Hex.decode("A4A5A6"));
|
||||||
|
|
||||||
|
DataWord horseKey = new DataWord(Hex.decode("B1B2B3"));
|
||||||
|
DataWord horseValue = new DataWord(Hex.decode("B4B5B6"));
|
||||||
|
|
||||||
|
track.addStorageRow(cow, cowKey, cowValue);
|
||||||
|
track.addStorageRow(horse, horseKey, horseValue);
|
||||||
|
|
||||||
|
assertEquals(cowValue, track.getStorageValue(cow, cowKey));
|
||||||
|
assertEquals(horseValue, track.getStorageValue(horse, horseKey));
|
||||||
|
|
||||||
|
track.rollback();
|
||||||
|
|
||||||
|
assertEquals(null, repository.getStorageValue(cow, cowKey));
|
||||||
|
assertEquals(null, repository.getStorageValue(horse, horseKey));
|
||||||
|
|
||||||
|
repository.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test11() {
|
||||||
|
|
||||||
|
SystemProperties.CONFIG.setDataBaseDir("test_db/" + RepositoryTest.class);
|
||||||
|
Repository repository = new RepositoryImpl(new LevelDbDataSource(), new LevelDbDataSource());
|
||||||
|
Repository track = repository.startTracking();
|
||||||
|
|
||||||
|
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
|
||||||
|
byte[] horse = Hex.decode("13978AEE95F38490E9769C39B2773ED763D9CD5F");
|
||||||
|
|
||||||
|
byte[] cowCode = Hex.decode("A1A2A3");
|
||||||
|
byte[] horseCode = Hex.decode("B1B2B3");
|
||||||
|
|
||||||
|
track.saveCode(cow, cowCode);
|
||||||
|
track.saveCode(horse, horseCode);
|
||||||
|
|
||||||
|
assertArrayEquals(cowCode, track.getCode(cow));
|
||||||
|
assertArrayEquals(horseCode, track.getCode(horse));
|
||||||
|
|
||||||
|
track.commit();
|
||||||
|
|
||||||
|
assertArrayEquals(cowCode, repository.getCode(cow));
|
||||||
|
assertArrayEquals(horseCode, repository.getCode(horse));
|
||||||
|
|
||||||
|
repository.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test12() {
|
||||||
|
|
||||||
|
SystemProperties.CONFIG.setDataBaseDir("test_db/" + RepositoryTest.class);
|
||||||
|
Repository repository = new RepositoryImpl(new LevelDbDataSource(), new LevelDbDataSource());
|
||||||
|
Repository track = repository.startTracking();
|
||||||
|
|
||||||
|
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
|
||||||
|
byte[] horse = Hex.decode("13978AEE95F38490E9769C39B2773ED763D9CD5F");
|
||||||
|
|
||||||
|
byte[] cowCode = Hex.decode("A1A2A3");
|
||||||
|
byte[] horseCode = Hex.decode("B1B2B3");
|
||||||
|
|
||||||
|
track.saveCode(cow, cowCode);
|
||||||
|
track.saveCode(horse, horseCode);
|
||||||
|
|
||||||
|
assertArrayEquals(cowCode, track.getCode(cow));
|
||||||
|
assertArrayEquals(horseCode, track.getCode(horse));
|
||||||
|
|
||||||
|
track.rollback();
|
||||||
|
|
||||||
|
assertArrayEquals(null, repository.getCode(cow));
|
||||||
|
assertArrayEquals(null, repository.getCode(horse));
|
||||||
|
|
||||||
|
repository.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // Let's upload genesis pre-mine just like in the real world
|
||||||
|
public void test13() {
|
||||||
|
|
||||||
|
SystemProperties.CONFIG.setDataBaseDir("test_db/" + RepositoryTest.class);
|
||||||
|
Repository repository = new RepositoryImpl(new LevelDbDataSource(), new LevelDbDataSource());
|
||||||
|
Repository track = repository.startTracking();
|
||||||
|
|
||||||
|
Genesis genesis = (Genesis)Genesis.getInstance();
|
||||||
|
for (ByteArrayWrapper key : genesis.getPremine().keySet()) {
|
||||||
|
repository.createAccount(key.getData());
|
||||||
|
repository.addBalance(key.getData(), genesis.getPremine().get(key).getBalance());
|
||||||
|
}
|
||||||
|
|
||||||
|
track.commit();
|
||||||
|
|
||||||
|
assertArrayEquals(Genesis.getInstance().getStateRoot(), repository.getRoot());
|
||||||
|
|
||||||
|
repository.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test14() {
|
||||||
|
|
||||||
|
SystemProperties.CONFIG.setDataBaseDir("test_db/" + RepositoryTest.class);
|
||||||
|
Repository repository = new RepositoryImpl(new LevelDbDataSource(), new LevelDbDataSource());
|
||||||
|
|
||||||
|
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
|
||||||
|
byte[] horse = Hex.decode("13978AEE95F38490E9769C39B2773ED763D9CD5F");
|
||||||
|
final BigInteger ELEVEN = BigInteger.TEN.add(BigInteger.ONE);
|
||||||
|
|
||||||
|
|
||||||
|
// changes level_1
|
||||||
|
Repository track1 = repository.startTracking();
|
||||||
|
track1.addBalance(cow, BigInteger.TEN);
|
||||||
|
track1.addBalance(horse, BigInteger.ONE);
|
||||||
|
|
||||||
|
assertEquals(BigInteger.TEN, track1.getBalance(cow));
|
||||||
|
assertEquals(BigInteger.ONE, track1.getBalance(horse));
|
||||||
|
|
||||||
|
|
||||||
|
// changes level_2
|
||||||
|
Repository track2 = track1.startTracking();
|
||||||
|
track2.addBalance(cow, BigInteger.ONE);
|
||||||
|
track2.addBalance(horse, BigInteger.TEN);
|
||||||
|
|
||||||
|
assertEquals(ELEVEN, track2.getBalance(cow));
|
||||||
|
assertEquals(ELEVEN, track2.getBalance(horse));
|
||||||
|
|
||||||
|
track2.commit();
|
||||||
|
track1.commit();
|
||||||
|
|
||||||
|
assertEquals(ELEVEN, repository.getBalance(cow));
|
||||||
|
assertEquals(ELEVEN, repository.getBalance(horse));
|
||||||
|
|
||||||
|
repository.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test15() {
|
||||||
|
|
||||||
|
SystemProperties.CONFIG.setDataBaseDir("test_db/" + RepositoryTest.class);
|
||||||
|
Repository repository = new RepositoryImpl(new LevelDbDataSource(), new LevelDbDataSource());
|
||||||
|
|
||||||
|
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
|
||||||
|
byte[] horse = Hex.decode("13978AEE95F38490E9769C39B2773ED763D9CD5F");
|
||||||
|
final BigInteger ELEVEN = BigInteger.TEN.add(BigInteger.ONE);
|
||||||
|
|
||||||
|
|
||||||
|
// changes level_1
|
||||||
|
Repository track1 = repository.startTracking();
|
||||||
|
track1.addBalance(cow, BigInteger.TEN);
|
||||||
|
track1.addBalance(horse, BigInteger.ONE);
|
||||||
|
|
||||||
|
assertEquals(BigInteger.TEN, track1.getBalance(cow));
|
||||||
|
assertEquals(BigInteger.ONE, track1.getBalance(horse));
|
||||||
|
|
||||||
|
// changes level_2
|
||||||
|
Repository track2 = track1.startTracking();
|
||||||
|
track2.addBalance(cow, BigInteger.ONE);
|
||||||
|
track2.addBalance(horse, BigInteger.TEN);
|
||||||
|
|
||||||
|
assertEquals(ELEVEN, track2.getBalance(cow));
|
||||||
|
assertEquals(ELEVEN, track2.getBalance(horse));
|
||||||
|
|
||||||
|
track2.rollback();
|
||||||
|
track1.commit();
|
||||||
|
|
||||||
|
assertEquals(BigInteger.TEN, repository.getBalance(cow));
|
||||||
|
assertEquals(BigInteger.ONE, repository.getBalance(horse));
|
||||||
|
|
||||||
|
repository.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test16() {
|
||||||
|
|
||||||
|
SystemProperties.CONFIG.setDataBaseDir("test_db/" + RepositoryTest.class);
|
||||||
|
Repository repository = new RepositoryImpl(new LevelDbDataSource(), new LevelDbDataSource());
|
||||||
|
|
||||||
|
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
|
||||||
|
byte[] horse = Hex.decode("13978AEE95F38490E9769C39B2773ED763D9CD5F");
|
||||||
|
|
||||||
|
byte[] cowKey1 = "key-c-1".getBytes();
|
||||||
|
byte[] cowValue1 = "val-c-1".getBytes();
|
||||||
|
|
||||||
|
byte[] horseKey1 = "key-h-1".getBytes();
|
||||||
|
byte[] horseValue1 = "val-h-1".getBytes();
|
||||||
|
|
||||||
|
byte[] cowKey2 = "key-c-2".getBytes();
|
||||||
|
byte[] cowValue2 = "val-c-2".getBytes();
|
||||||
|
|
||||||
|
byte[] horseKey2 = "key-h-2".getBytes();
|
||||||
|
byte[] horseValue2 = "val-h-2".getBytes();
|
||||||
|
|
||||||
|
// changes level_1
|
||||||
|
Repository track1 = repository.startTracking();
|
||||||
|
track1.addStorageRow(cow, new DataWord(cowKey1), new DataWord(cowValue1));
|
||||||
|
track1.addStorageRow(horse, new DataWord(horseKey1), new DataWord(horseValue1));
|
||||||
|
|
||||||
|
assertEquals(new DataWord(cowValue1), track1.getStorageValue(cow, new DataWord(cowKey1)));
|
||||||
|
assertEquals(new DataWord(horseValue1), track1.getStorageValue(horse, new DataWord(horseKey1)));
|
||||||
|
|
||||||
|
// changes level_2
|
||||||
|
Repository track2 = track1.startTracking();
|
||||||
|
track2.addStorageRow(cow, new DataWord(cowKey2), new DataWord(cowValue2));
|
||||||
|
track2.addStorageRow(horse, new DataWord(horseKey2), new DataWord(horseValue2));
|
||||||
|
|
||||||
|
assertEquals(new DataWord(cowValue1), track2.getStorageValue(cow, new DataWord(cowKey1)));
|
||||||
|
assertEquals(new DataWord(horseValue1), track2.getStorageValue(horse, new DataWord(horseKey1)));
|
||||||
|
|
||||||
|
assertEquals(new DataWord(cowValue2), track2.getStorageValue(cow, new DataWord(cowKey2)));
|
||||||
|
assertEquals(new DataWord(horseValue2), track2.getStorageValue(horse, new DataWord(horseKey2)));
|
||||||
|
|
||||||
|
track2.commit();
|
||||||
|
// leaving level_2
|
||||||
|
|
||||||
|
assertEquals(new DataWord(cowValue1), track1.getStorageValue(cow, new DataWord(cowKey1)));
|
||||||
|
assertEquals(new DataWord(horseValue1), track1.getStorageValue(horse, new DataWord(horseKey1)));
|
||||||
|
|
||||||
|
assertEquals(new DataWord(cowValue2), track1.getStorageValue(cow, new DataWord(cowKey2)));
|
||||||
|
assertEquals(new DataWord(horseValue2), track1.getStorageValue(horse, new DataWord(horseKey2)));
|
||||||
|
|
||||||
|
|
||||||
|
track1.commit();
|
||||||
|
// leaving level_1
|
||||||
|
|
||||||
|
assertEquals(new DataWord(cowValue1), repository.getStorageValue(cow, new DataWord(cowKey1)));
|
||||||
|
assertEquals(new DataWord(horseValue1), repository.getStorageValue(horse, new DataWord(horseKey1)));
|
||||||
|
|
||||||
|
assertEquals(new DataWord(cowValue2), repository.getStorageValue(cow, new DataWord(cowKey2)));
|
||||||
|
assertEquals(new DataWord(horseValue2), repository.getStorageValue(horse, new DataWord(horseKey2)));
|
||||||
|
|
||||||
|
repository.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test17() {
|
||||||
|
|
||||||
|
SystemProperties.CONFIG.setDataBaseDir("test_db/" + RepositoryTest.class);
|
||||||
|
Repository repository = new RepositoryImpl(new LevelDbDataSource(), new LevelDbDataSource());
|
||||||
|
|
||||||
|
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
|
||||||
|
|
||||||
|
byte[] cowKey1 = "key-c-1".getBytes();
|
||||||
|
byte[] cowValue1 = "val-c-1".getBytes();
|
||||||
|
|
||||||
|
// changes level_1
|
||||||
|
Repository track1 = repository.startTracking();
|
||||||
|
|
||||||
|
// changes level_2
|
||||||
|
Repository track2 = track1.startTracking();
|
||||||
|
track2.addStorageRow(cow, new DataWord(cowKey1), new DataWord(cowValue1));
|
||||||
|
assertEquals(new DataWord(cowValue1), track2.getStorageValue(cow, new DataWord(cowKey1)));
|
||||||
|
track2.rollback();
|
||||||
|
// leaving level_2
|
||||||
|
|
||||||
|
track1.commit();
|
||||||
|
// leaving level_1
|
||||||
|
|
||||||
|
Assert.assertEquals(Hex.toHexString(HashUtil.EMPTY_TRIE_HASH), Hex.toHexString(repository.getRoot()));
|
||||||
|
repository.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test18() {
|
||||||
|
|
||||||
|
SystemProperties.CONFIG.setDataBaseDir("test_db/" + RepositoryTest.class);
|
||||||
|
Repository repoTrack = new RepositoryTrack(); // dummy
|
||||||
|
Repository repoTrack2 = repoTrack.startTracking(); //track
|
||||||
|
|
||||||
|
byte[] cow = Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826");
|
||||||
|
byte[] horse = Hex.decode("13978AEE95F38490E9769C39B2773ED763D9CD5F");
|
||||||
|
byte[] pig = Hex.decode("F0B8C9D84DD2B877E0B952130B73E218106FEC04");
|
||||||
|
byte[] precompiled = Hex.decode("0000000000000000000000000000000000000002");
|
||||||
|
|
||||||
|
byte[] cowCode = Hex.decode("A1A2A3");
|
||||||
|
byte[] horseCode = Hex.decode("B1B2B3");
|
||||||
|
|
||||||
|
repoTrack.saveCode(cow, cowCode);
|
||||||
|
repoTrack.saveCode(horse, horseCode);
|
||||||
|
|
||||||
|
repoTrack.delete(horse);
|
||||||
|
|
||||||
|
assertEquals(true, repoTrack2.isExist(cow));
|
||||||
|
assertEquals(false, repoTrack2.isExist(horse));
|
||||||
|
assertEquals(false, repoTrack2.isExist(pig));
|
||||||
|
assertEquals(false, repoTrack2.isExist(precompiled));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
package org.ethereum.db;
|
||||||
|
|
||||||
|
import org.ethereum.datasource.KeyValueDataSource;
|
||||||
|
import org.ethereum.datasource.LevelDbDataSource;
|
||||||
|
|
||||||
|
import org.iq80.leveldb.Options;
|
||||||
|
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static org.iq80.leveldb.impl.Iq80DBFactory.factory;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Roman Mandeleil
|
||||||
|
* @since 11.06.2014
|
||||||
|
*/
|
||||||
|
public class TrackDatabaseTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test1() {
|
||||||
|
|
||||||
|
KeyValueDataSource keyValueDataSource = new LevelDbDataSource("temp");
|
||||||
|
keyValueDataSource.init();
|
||||||
|
|
||||||
|
DatabaseImpl db1 = new DatabaseImpl(keyValueDataSource);
|
||||||
|
TrackDatabase trackDatabase1 = new TrackDatabase(db1);
|
||||||
|
|
||||||
|
trackDatabase1.put(Hex.decode("abcdef"), Hex.decode("abcdef"));
|
||||||
|
byte[] value = trackDatabase1.get(Hex.decode("abcdef"));
|
||||||
|
assertEquals("abcdef", Hex.toHexString(value));
|
||||||
|
|
||||||
|
trackDatabase1.startTrack();
|
||||||
|
trackDatabase1.put(Hex.decode("abcdef"), Hex.decode("ffffff"));
|
||||||
|
value = trackDatabase1.get(Hex.decode("abcdef"));
|
||||||
|
assertEquals("ffffff", Hex.toHexString(value));
|
||||||
|
|
||||||
|
trackDatabase1.rollbackTrack();
|
||||||
|
value = trackDatabase1.get(Hex.decode("abcdef"));
|
||||||
|
assertEquals("abcdef", Hex.toHexString(value));
|
||||||
|
|
||||||
|
trackDatabase1.startTrack();
|
||||||
|
trackDatabase1.put(Hex.decode("abcdef"), Hex.decode("ffffff"));
|
||||||
|
trackDatabase1.commitTrack();
|
||||||
|
value = trackDatabase1.get(Hex.decode("abcdef"));
|
||||||
|
assertEquals("ffffff", Hex.toHexString(value));
|
||||||
|
|
||||||
|
db1.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void destroyDB() {
|
||||||
|
try {
|
||||||
|
Options options = new Options();
|
||||||
|
factory.destroy(new File("temp"), options);
|
||||||
|
} catch (IOException e) {
|
||||||
|
fail("Destroying temp-db failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package org.ethereum.di.components;
|
||||||
|
|
||||||
|
import org.ethereum.di.modules.EthereumModule;
|
||||||
|
import org.ethereum.facade.Ethereum;
|
||||||
|
import org.ethereum.listener.EthereumListener;
|
||||||
|
import org.ethereum.manager.WorldManager;
|
||||||
|
import org.ethereum.net.server.ChannelManager;
|
||||||
|
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import dagger.Component;
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
@Component(modules = EthereumModule.class)
|
||||||
|
public interface TestEthereumComponent {
|
||||||
|
|
||||||
|
void inject(ChannelManager channelManager);
|
||||||
|
void inject(WorldManager worldManager);
|
||||||
|
|
||||||
|
Ethereum ethereum();
|
||||||
|
EthereumListener listener();
|
||||||
|
ChannelManager channelManager();
|
||||||
|
WorldManager worldManager();
|
||||||
|
}
|
|
@ -0,0 +1,160 @@
|
||||||
|
package org.ethereum.di.modules;
|
||||||
|
|
||||||
|
import org.ethereum.config.SystemProperties;
|
||||||
|
import org.ethereum.core.BlockchainImpl;
|
||||||
|
import org.ethereum.core.Wallet;
|
||||||
|
import org.ethereum.datasource.LevelDbDataSource;
|
||||||
|
import org.ethereum.db.BlockStore;
|
||||||
|
import org.ethereum.db.InMemoryBlockStore;
|
||||||
|
import org.ethereum.db.RepositoryImpl;
|
||||||
|
import org.ethereum.facade.Blockchain;
|
||||||
|
import org.ethereum.facade.Ethereum;
|
||||||
|
import org.ethereum.facade.EthereumImpl;
|
||||||
|
import org.ethereum.facade.Repository;
|
||||||
|
import org.ethereum.listener.CompositeEthereumListener;
|
||||||
|
import org.ethereum.listener.EthereumListener;
|
||||||
|
import org.ethereum.manager.AdminInfo;
|
||||||
|
import org.ethereum.manager.BlockLoader;
|
||||||
|
import org.ethereum.manager.WorldManager;
|
||||||
|
import org.ethereum.net.MessageQueue;
|
||||||
|
import org.ethereum.net.client.PeerClient;
|
||||||
|
import org.ethereum.net.eth.EthHandler;
|
||||||
|
import org.ethereum.net.p2p.P2pHandler;
|
||||||
|
import org.ethereum.net.peerdiscovery.DiscoveryChannel;
|
||||||
|
import org.ethereum.net.peerdiscovery.PeerDiscovery;
|
||||||
|
import org.ethereum.net.peerdiscovery.WorkerThread;
|
||||||
|
import org.ethereum.net.server.ChannelManager;
|
||||||
|
import org.ethereum.net.server.EthereumChannelInitializer;
|
||||||
|
import org.ethereum.net.shh.ShhHandler;
|
||||||
|
import org.ethereum.net.wire.MessageCodec;
|
||||||
|
import org.ethereum.vm.ProgramInvokeFactory;
|
||||||
|
import org.ethereum.vm.ProgramInvokeFactoryImpl;
|
||||||
|
|
||||||
|
import javax.inject.Provider;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import dagger.Module;
|
||||||
|
import dagger.Provides;
|
||||||
|
|
||||||
|
@Module
|
||||||
|
public class TestEthereumModule {
|
||||||
|
|
||||||
|
public TestEthereumModule() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
Ethereum provideEthereum(WorldManager worldManager, AdminInfo adminInfo, ChannelManager channelManager,
|
||||||
|
BlockLoader blockLoader, Provider<PeerClient> peerClientProvider, EthereumListener listener) {
|
||||||
|
return new EthereumImpl(worldManager, adminInfo, channelManager, blockLoader, peerClientProvider, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
WorldManager provideWorldManager(Blockchain blockchain, Repository repository, Wallet wallet, PeerDiscovery peerDiscovery
|
||||||
|
,BlockStore blockStore, ChannelManager channelManager, AdminInfo adminInfo, EthereumListener listener) {
|
||||||
|
return new WorldManager(blockchain, repository, wallet, peerDiscovery, blockStore, channelManager, adminInfo, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
Blockchain provideBlockchain(BlockStore blockStore, Repository repository,
|
||||||
|
Wallet wallet, AdminInfo adminInfo,
|
||||||
|
EthereumListener listener, ChannelManager channelManager) {
|
||||||
|
return new BlockchainImpl(blockStore, repository, wallet, adminInfo, listener, channelManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
BlockStore provideBlockStore() {
|
||||||
|
return new InMemoryBlockStore();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
Repository provideRepository() {
|
||||||
|
LevelDbDataSource detailsDS = new LevelDbDataSource();
|
||||||
|
LevelDbDataSource stateDS = new LevelDbDataSource();
|
||||||
|
return new RepositoryImpl(detailsDS, stateDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
AdminInfo provideAdminInfo() {
|
||||||
|
return new AdminInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
EthereumListener provideEthereumListener() {
|
||||||
|
return new CompositeEthereumListener();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
PeerDiscovery providePeerDiscovery() {
|
||||||
|
return new PeerDiscovery();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
ChannelManager provideChannelManager(EthereumListener listener) {
|
||||||
|
return new ChannelManager(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
BlockLoader provideBlockLoader(Blockchain blockchain) {
|
||||||
|
return new BlockLoader(blockchain);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
ProgramInvokeFactory provideProgramInvokeFactory() {
|
||||||
|
return new ProgramInvokeFactoryImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
EthHandler provideEthHandler(Blockchain blockchain, EthereumListener listener, Wallet wallet) {
|
||||||
|
return new EthHandler(blockchain, listener, wallet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
ShhHandler provideShhHandler(EthereumListener listener) {
|
||||||
|
return new ShhHandler(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
P2pHandler provideP2pHandler(PeerDiscovery peerDiscovery, EthereumListener listener) {
|
||||||
|
return new P2pHandler(peerDiscovery, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
MessageCodec provideMessageCodec(EthereumListener listener) {
|
||||||
|
return new MessageCodec(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
PeerClient providePeerClient(EthereumListener listener, ChannelManager channelManager,
|
||||||
|
Provider<EthereumChannelInitializer> ethereumChannelInitializerProvider) {
|
||||||
|
return new PeerClient(listener, channelManager, ethereumChannelInitializerProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
MessageQueue provideMessageQueue(EthereumListener listener) {
|
||||||
|
return new MessageQueue(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
WorkerThread provideWorkerThread(Provider<DiscoveryChannel> discoveryChannelProvider) {
|
||||||
|
return new WorkerThread(discoveryChannelProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
String provideRemoteId() {
|
||||||
|
return SystemProperties.CONFIG.activePeerNodeid();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,112 @@
|
||||||
|
package org.ethereum.jsontestsuite;
|
||||||
|
|
||||||
|
import org.json.simple.parser.ParseException;
|
||||||
|
import org.junit.FixMethodOrder;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runners.MethodSorters;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
|
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||||
|
public class GitHubBlockTest {
|
||||||
|
|
||||||
|
//SHACOMMIT of tested commit, ethereum/tests.git
|
||||||
|
public String shacommit = "d2ba02fe0507da205e3d17d79612ae15282b35a2";
|
||||||
|
|
||||||
|
@Ignore
|
||||||
|
@Test
|
||||||
|
public void runSingleTest() throws ParseException, IOException {
|
||||||
|
String json = JSONReader.loadJSONFromCommit("BlockTests/bcUncleTest.json", shacommit);
|
||||||
|
GitHubJSONTestSuite.runGitHubJsonSingleBlockTest(json, "oneUncleGeneration7");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Ignore
|
||||||
|
@Test
|
||||||
|
public void runBCBlockChainTest() throws ParseException, IOException {
|
||||||
|
Set<String> excluded = new HashSet<>();
|
||||||
|
String json = JSONReader.loadJSONFromCommit("BlockTests/bcInvalidHeaderTest.json", shacommit);
|
||||||
|
//TODO fix via blockchain rollbacks
|
||||||
|
excluded.add("wrongGasUsed");
|
||||||
|
excluded.add("wrongStateRoot");
|
||||||
|
//TODO need to make sure the checks match the cpp
|
||||||
|
//excluded.add("wrongParentHash");
|
||||||
|
//excluded.add("wrongTimestamp");
|
||||||
|
//TODO need to add some way to roll back repository from BlockChain.add()
|
||||||
|
excluded.add("wrongReceiptTrie");
|
||||||
|
excluded.add("log1_wrongBloom");
|
||||||
|
|
||||||
|
GitHubJSONTestSuite.runGitHubJsonBlockTest(json,excluded);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Ignore
|
||||||
|
@Test
|
||||||
|
public void runBCInvalidRLPTest() throws ParseException, IOException {
|
||||||
|
Set<String> excluded = new HashSet<>();
|
||||||
|
String json = JSONReader.loadJSONFromCommit("BlockTests/bcInvalidRLPTest.json", shacommit);
|
||||||
|
excluded.add("BLOCK_stateRoot_GivenAsList");
|
||||||
|
excluded.add("BLOCK_difficulty_GivenAsList");
|
||||||
|
excluded.add("BLOCK_mixHash_TooShort");
|
||||||
|
excluded.add("BLOCK__RandomByteAtRLP_8");
|
||||||
|
excluded.add("BLOCK__RandomByteAtRLP_9");
|
||||||
|
excluded.add("BLOCK__RandomByteAtRLP_7");
|
||||||
|
excluded.add("BLOCK__RandomByteAtRLP_6");
|
||||||
|
excluded.add("BLOCK__RandomByteAtRLP_5");
|
||||||
|
excluded.add("BLOCK__RandomByteAtRLP_4");
|
||||||
|
excluded.add("BLOCK_stateRoot_TooShort");
|
||||||
|
excluded.add("BLOCK_gasUsed_TooLarge");
|
||||||
|
excluded.add("BLOCK_stateRoot_TooLarge");
|
||||||
|
excluded.add("BLOCK_receiptTrie_Prefixed0000");
|
||||||
|
excluded.add("BLOCK_transactionsTrie_TooLarge");
|
||||||
|
excluded.add("TRANSCT_gasLimit_Prefixed0000");
|
||||||
|
excluded.add("TRANSCT_gasLimit_GivenAsList");
|
||||||
|
excluded.add("TRANSCT_svalue_TooLarge");
|
||||||
|
excluded.add("TRANSCT_svalue_TooShort");
|
||||||
|
excluded.add("TRANSCT_svalue_GivenAsList");
|
||||||
|
excluded.add("TRANSCT__RandomByteAtTheEnd");
|
||||||
|
//GitHubJSONTestSuite.runGitHubJsonBlockTest(json, excluded);
|
||||||
|
GitHubJSONTestSuite.runGitHubJsonSingleBlockTest(json, "TRANSCT__RandomByteAtTheEnd");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Ignore
|
||||||
|
@Test
|
||||||
|
public void runBCJSAPITest() throws ParseException, IOException {
|
||||||
|
Set<String> excluded = new HashSet<>();
|
||||||
|
String json = JSONReader.loadJSONFromCommit("BlockTests/bcJS_API_Test.json", shacommit);
|
||||||
|
excluded.add("JS_API_Tests");
|
||||||
|
GitHubJSONTestSuite.runGitHubJsonBlockTest(json, excluded);
|
||||||
|
}
|
||||||
|
|
||||||
|
//@Ignore
|
||||||
|
@Test
|
||||||
|
public void runBCUncleHeaderValidityTest() throws ParseException, IOException {
|
||||||
|
Set<String> excluded = new HashSet<>();
|
||||||
|
String json = JSONReader.loadJSONFromCommit("BlockTests/bcUncleHeaderValiditiy.json", shacommit);
|
||||||
|
//TODO need to make sure these are not passing on accident
|
||||||
|
//excluded.add("timestampTooLow");
|
||||||
|
//excluded.add("timestampTooHigh");
|
||||||
|
//excluded.add("wrongParentHash");
|
||||||
|
GitHubJSONTestSuite.runGitHubJsonBlockTest(json, excluded);
|
||||||
|
}
|
||||||
|
|
||||||
|
//@Ignore
|
||||||
|
@Test
|
||||||
|
public void runBCUncleTest() throws ParseException, IOException {
|
||||||
|
Set<String> excluded = new HashSet<>();
|
||||||
|
String json = JSONReader.loadJSONFromCommit("BlockTests/bcUncleTest.json", shacommit);
|
||||||
|
GitHubJSONTestSuite.runGitHubJsonBlockTest(json, excluded);
|
||||||
|
}
|
||||||
|
|
||||||
|
//@Ignore
|
||||||
|
@Test
|
||||||
|
public void runBCValidBlockTest() throws ParseException, IOException {
|
||||||
|
String json = JSONReader.loadJSONFromCommit("BlockTests/bcValidBlockTest.json", shacommit);
|
||||||
|
GitHubJSONTestSuite.runGitHubJsonBlockTest(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package org.ethereum.jsontestsuite;
|
||||||
|
|
||||||
|
import org.codehaus.jackson.map.ObjectMapper;
|
||||||
|
import org.codehaus.jackson.type.JavaType;
|
||||||
|
import org.json.simple.parser.ParseException;
|
||||||
|
import org.junit.FixMethodOrder;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runners.MethodSorters;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
|
||||||
|
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||||
|
public class GitHubCryptoTest {
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAllInCryptoSute() throws ParseException, IOException {
|
||||||
|
|
||||||
|
String json = JSONReader.loadJSON("BasicTests/crypto.json");
|
||||||
|
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
JavaType type = mapper.getTypeFactory().
|
||||||
|
constructMapType(HashMap.class, String.class, CryptoTestCase.class);
|
||||||
|
|
||||||
|
|
||||||
|
HashMap<String , CryptoTestCase> testSuite =
|
||||||
|
mapper.readValue(json, type);
|
||||||
|
|
||||||
|
for (String key : testSuite.keySet()){
|
||||||
|
|
||||||
|
System.out.println("executing: " + key);
|
||||||
|
testSuite.get(key).execute();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,237 @@
|
||||||
|
package org.ethereum.jsontestsuite;
|
||||||
|
|
||||||
|
import org.ethereum.jsontestsuite.runners.StateTestRunner;
|
||||||
|
import org.json.simple.JSONObject;
|
||||||
|
import org.json.simple.parser.JSONParser;
|
||||||
|
import org.json.simple.parser.ParseException;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Assume;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test file specific for tests maintained in the GitHub repository
|
||||||
|
* by the Ethereum DEV team. <br/>
|
||||||
|
*
|
||||||
|
* @see <a href="https://github.com/ethereum/tests/">https://github.com/ethereum/tests/</a>
|
||||||
|
*/
|
||||||
|
public class GitHubJSONTestSuite {
|
||||||
|
|
||||||
|
private static Logger logger = LoggerFactory.getLogger("TCK-Test");
|
||||||
|
|
||||||
|
|
||||||
|
protected static void runGitHubJsonVMTest(String json, String testName) throws ParseException {
|
||||||
|
Assume.assumeFalse("Online test is not available", json.equals(""));
|
||||||
|
|
||||||
|
JSONParser parser = new JSONParser();
|
||||||
|
JSONObject testSuiteObj = (JSONObject) parser.parse(json);
|
||||||
|
|
||||||
|
TestSuite testSuite = new TestSuite(testSuiteObj);
|
||||||
|
Iterator<TestCase> testIterator = testSuite.iterator();
|
||||||
|
|
||||||
|
for (TestCase testCase : testSuite.getAllTests()) {
|
||||||
|
|
||||||
|
String prefix = " ";
|
||||||
|
if (testName.equals(testCase.getName())) prefix = " => ";
|
||||||
|
|
||||||
|
logger.info(prefix + testCase.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
while (testIterator.hasNext()) {
|
||||||
|
|
||||||
|
TestCase testCase = testIterator.next();
|
||||||
|
if (testName.equals((testCase.getName()))) {
|
||||||
|
TestRunner runner = new TestRunner();
|
||||||
|
List<String> result = runner.runTestCase(testCase);
|
||||||
|
Assert.assertTrue(result.isEmpty());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static void runGitHubJsonVMTest(String json) throws ParseException {
|
||||||
|
Set<String> excluded = new HashSet<>();
|
||||||
|
runGitHubJsonVMTest(json, excluded);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected static void runGitHubJsonVMTest(String json, Set<String> excluded) throws ParseException {
|
||||||
|
Assume.assumeFalse("Online test is not available", json.equals(""));
|
||||||
|
|
||||||
|
JSONParser parser = new JSONParser();
|
||||||
|
JSONObject testSuiteObj = (JSONObject) parser.parse(json);
|
||||||
|
|
||||||
|
TestSuite testSuite = new TestSuite(testSuiteObj);
|
||||||
|
Iterator<TestCase> testIterator = testSuite.iterator();
|
||||||
|
|
||||||
|
for (TestCase testCase : testSuite.getAllTests()) {
|
||||||
|
|
||||||
|
String prefix = " ";
|
||||||
|
if (excluded.contains(testCase.getName())) prefix = "[X] ";
|
||||||
|
|
||||||
|
logger.info(prefix + testCase.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
while (testIterator.hasNext()) {
|
||||||
|
|
||||||
|
TestCase testCase = testIterator.next();
|
||||||
|
if (excluded.contains(testCase.getName()))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
TestRunner runner = new TestRunner();
|
||||||
|
List<String> result = runner.runTestCase(testCase);
|
||||||
|
Assert.assertTrue(result.isEmpty());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected static void runGitHubJsonSingleBlockTest(String json, String testName) throws ParseException, IOException {
|
||||||
|
|
||||||
|
BlockTestSuite testSuite = new BlockTestSuite(json);
|
||||||
|
Set<String> testCollection = testSuite.getTestCases().keySet();
|
||||||
|
|
||||||
|
for (String testCase : testCollection) {
|
||||||
|
if (testCase.equals(testName))
|
||||||
|
logger.info(" => " + testCase);
|
||||||
|
else
|
||||||
|
logger.info(" " + testCase);
|
||||||
|
}
|
||||||
|
|
||||||
|
runSingleBlockTest(testSuite, testName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected static void runGitHubJsonBlockTest(String json, Set<String> excluded) throws ParseException, IOException {
|
||||||
|
Assume.assumeFalse("Online test is not available", json.equals(""));
|
||||||
|
|
||||||
|
BlockTestSuite testSuite = new BlockTestSuite(json);
|
||||||
|
Set<String> testCollection = testSuite.getTestCases().keySet();
|
||||||
|
|
||||||
|
for (String testName : testCollection) {
|
||||||
|
|
||||||
|
if ( excluded.contains(testName)) {
|
||||||
|
logger.info(" Not running: " + testName);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
runSingleBlockTest(testSuite, testName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static void runGitHubJsonBlockTest(String json) throws ParseException, IOException {
|
||||||
|
Set<String> excluded = new HashSet<>();
|
||||||
|
runGitHubJsonBlockTest(json, excluded);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void runSingleBlockTest(BlockTestSuite testSuite, String testName){
|
||||||
|
|
||||||
|
BlockTestCase blockTestCase = testSuite.getTestCases().get(testName);
|
||||||
|
TestRunner runner = new TestRunner();
|
||||||
|
|
||||||
|
logger.info("\n\n ***************** Running test: {} ***************************** \n\n", testName);
|
||||||
|
List<String> result = runner.runTestCase(blockTestCase);
|
||||||
|
|
||||||
|
if (!result.isEmpty())
|
||||||
|
for (String single : result)
|
||||||
|
logger.info(single);
|
||||||
|
|
||||||
|
Assert.assertTrue(result.isEmpty());
|
||||||
|
logger.info(" \n\n *********************** Passed: " + testName + " ************************** \n\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void runStateTest(String jsonSuite) throws IOException {
|
||||||
|
runStateTest(jsonSuite, new HashSet<String>());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void runStateTest(String jsonSuite, String testName) throws IOException {
|
||||||
|
|
||||||
|
StateTestSuite stateTestSuite = new StateTestSuite(jsonSuite);
|
||||||
|
Map<String, StateTestCase> testCases = stateTestSuite.getTestCases();
|
||||||
|
|
||||||
|
for (String testCase : testCases.keySet()) {
|
||||||
|
if (testCase.equals(testName))
|
||||||
|
logger.info(" => " + testCase);
|
||||||
|
else
|
||||||
|
logger.info(" " + testCase);
|
||||||
|
}
|
||||||
|
|
||||||
|
StateTestCase testCase = testCases.get(testName);
|
||||||
|
if (testCase != null){
|
||||||
|
String output = String.format("* running: %s *", testName);
|
||||||
|
String line = output.replaceAll(".", "*");
|
||||||
|
|
||||||
|
logger.info(line);
|
||||||
|
logger.info(output);
|
||||||
|
logger.info(line);
|
||||||
|
List<String> fails = StateTestRunner.run(testCases.get(testName));
|
||||||
|
|
||||||
|
Assert.assertTrue(fails.size() == 0);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
logger.error("Sorry test case doesn't exist: {}", testName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void runStateTest(String jsonSuite, Set<String> excluded) throws IOException {
|
||||||
|
|
||||||
|
StateTestSuite stateTestSuite = new StateTestSuite(jsonSuite);
|
||||||
|
Map<String, StateTestCase> testCases = stateTestSuite.getTestCases();
|
||||||
|
Map<String, Boolean> summary = new HashMap<>();
|
||||||
|
|
||||||
|
|
||||||
|
for (String testCase : testCases.keySet()) {
|
||||||
|
if ( excluded.contains(testCase))
|
||||||
|
logger.info(" [X] " + testCase);
|
||||||
|
else
|
||||||
|
logger.info(" " + testCase);
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<String> testNames = stateTestSuite.getTestCases().keySet();
|
||||||
|
for (String testName : testNames){
|
||||||
|
|
||||||
|
if (excluded.contains(testName)) continue;
|
||||||
|
String output = String.format("* running: %s *", testName);
|
||||||
|
String line = output.replaceAll(".", "*");
|
||||||
|
|
||||||
|
logger.info(line);
|
||||||
|
logger.info(output);
|
||||||
|
logger.info(line);
|
||||||
|
|
||||||
|
List<String> result = StateTestRunner.run(testCases.get(testName));
|
||||||
|
if (!result.isEmpty())
|
||||||
|
summary.put(testName, false);
|
||||||
|
else
|
||||||
|
summary.put(testName, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("Summary: ");
|
||||||
|
logger.info("=========");
|
||||||
|
|
||||||
|
int fails = 0; int pass = 0;
|
||||||
|
for (String key : summary.keySet()){
|
||||||
|
|
||||||
|
if (summary.get(key)) ++pass; else ++fails;
|
||||||
|
String sumTest = String.format("%-60s:^%s", key, (summary.get(key) ? "PASS" : "FAIL")).
|
||||||
|
replace(' ', '.').
|
||||||
|
replace("^", " ");
|
||||||
|
logger.info(sumTest);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info(" - Total: Pass: {}, Failed: {} - ", pass, fails);
|
||||||
|
|
||||||
|
Assert.assertTrue(fails == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,176 @@
|
||||||
|
package org.ethereum.jsontestsuite;
|
||||||
|
|
||||||
|
import org.json.simple.parser.ParseException;
|
||||||
|
|
||||||
|
import org.junit.FixMethodOrder;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runners.MethodSorters;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.ethereum.jsontestsuite.JSONReader.getFileNamesForTreeSha;
|
||||||
|
|
||||||
|
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||||
|
public class GitHubStateTest {
|
||||||
|
|
||||||
|
//SHACOMMIT of tested commit, ethereum/tests.git
|
||||||
|
public String shacommit = "d2ba02fe0507da205e3d17d79612ae15282b35a2";
|
||||||
|
|
||||||
|
|
||||||
|
@Ignore
|
||||||
|
@Test // this method is mostly for hands-on convenient testing
|
||||||
|
public void stSingleTest() throws ParseException, IOException {
|
||||||
|
String json = JSONReader.loadJSONFromCommit("StateTests/stMemoryTest.json", shacommit);
|
||||||
|
GitHubJSONTestSuite.runStateTest(json, "stackLimitPush32_1025");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void stExample() throws ParseException, IOException {
|
||||||
|
Set<String> excluded = new HashSet<>();
|
||||||
|
String json = JSONReader.loadJSONFromCommit("StateTests/stExample.json", shacommit);
|
||||||
|
GitHubJSONTestSuite.runStateTest(json, excluded);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void stCallCreateCallCodeTest() throws ParseException, IOException {
|
||||||
|
Set<String> excluded = new HashSet<>();
|
||||||
|
excluded.add("createJS_ExampleContract"); //FIXME Bug on CPP testrunner, storage/SSTORE
|
||||||
|
excluded.add("Callcode1024OOG");
|
||||||
|
excluded.add("Call1024OOG");
|
||||||
|
excluded.add("callcodeWithHighValue");
|
||||||
|
excluded.add("callWithHighValue");
|
||||||
|
String json = JSONReader.loadJSONFromCommit("StateTests/stCallCreateCallCodeTest.json", shacommit);
|
||||||
|
GitHubJSONTestSuite.runStateTest(json, excluded);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void stInitCodeTest() throws ParseException, IOException {
|
||||||
|
Set<String> excluded = new HashSet<>();
|
||||||
|
String json = JSONReader.loadJSONFromCommit("StateTests/stInitCodeTest.json", shacommit);
|
||||||
|
GitHubJSONTestSuite.runStateTest(json, excluded);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void stLogTests() throws ParseException, IOException {
|
||||||
|
Set<String> excluded = new HashSet<>();
|
||||||
|
String json = JSONReader.loadJSONFromCommit("StateTests/stLogTests.json", shacommit);
|
||||||
|
GitHubJSONTestSuite.runStateTest(json, excluded);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void stPreCompiledContracts() throws ParseException, IOException {
|
||||||
|
Set<String> excluded = new HashSet<>();
|
||||||
|
String json = JSONReader.loadJSONFromCommit("StateTests/stPreCompiledContracts.json", shacommit);
|
||||||
|
GitHubJSONTestSuite.runStateTest(json, excluded);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void stMemoryStressTest() throws ParseException, IOException {
|
||||||
|
Set<String> excluded = new HashSet<>();
|
||||||
|
excluded.add("mload32bitBound_return2");//FIXME memorySave must support long
|
||||||
|
excluded.add("mload32bitBound_return"); //FIXME memorySave must support long
|
||||||
|
excluded.add("mload32bitBound_Msize"); //FIXME memoryChunk must support long
|
||||||
|
String json = JSONReader.loadJSONFromCommit("StateTests/stMemoryStressTest.json", shacommit);
|
||||||
|
GitHubJSONTestSuite.runStateTest(json, excluded);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void stMemoryTest() throws ParseException, IOException {
|
||||||
|
String json = JSONReader.loadJSONFromCommit("StateTests/stMemoryTest.json", shacommit);
|
||||||
|
Set<String> excluded = new HashSet<>();
|
||||||
|
GitHubJSONTestSuite.runStateTest(json, excluded);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Ignore
|
||||||
|
@Test
|
||||||
|
public void stQuadraticComplexityTest() throws ParseException, IOException {
|
||||||
|
Set<String> excluded = new HashSet<>();
|
||||||
|
String json = JSONReader.loadJSONFromCommit("StateTests/stQuadraticComplexityTest.json", shacommit);
|
||||||
|
GitHubJSONTestSuite.runStateTest(json, excluded);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Ignore
|
||||||
|
@Test
|
||||||
|
public void stSolidityTest() throws ParseException, IOException {
|
||||||
|
Set<String> excluded = new HashSet<>();
|
||||||
|
excluded.add("TestBlockAndTransactionProperties"); //TODO proper BigInt block support needed
|
||||||
|
String json = JSONReader.loadJSONFromCommit("StateTests/stSolidityTest.json", shacommit);
|
||||||
|
GitHubJSONTestSuite.runStateTest(json, excluded);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void stRecursiveCreate() throws ParseException, IOException {
|
||||||
|
Set<String> excluded = new HashSet<>();
|
||||||
|
String json = JSONReader.loadJSONFromCommit("StateTests/stRecursiveCreate.json", shacommit);
|
||||||
|
GitHubJSONTestSuite.runStateTest(json, excluded);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void stRefundTest() throws ParseException, IOException {
|
||||||
|
Set<String> excluded = new HashSet<>();
|
||||||
|
String json = JSONReader.loadJSONFromCommit("StateTests/stRefundTest.json", shacommit);
|
||||||
|
GitHubJSONTestSuite.runStateTest(json, excluded);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void stSpecialTest() throws ParseException, IOException {
|
||||||
|
Set<String> excluded = new HashSet<>();
|
||||||
|
String json = JSONReader.loadJSONFromCommit("StateTests/stSpecialTest.json", shacommit);
|
||||||
|
GitHubJSONTestSuite.runStateTest(json, excluded);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void stBlockHashTest() throws ParseException, IOException {
|
||||||
|
String json = JSONReader.loadJSONFromCommit("StateTests/stBlockHashTest.json", shacommit);
|
||||||
|
GitHubJSONTestSuite.runStateTest(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
//@Ignore
|
||||||
|
@Test
|
||||||
|
public void stSystemOperationsTest() throws IOException {
|
||||||
|
Set<String> excluded = new HashSet<>();
|
||||||
|
excluded.add("CallRecursiveBomb0_OOG_atMaxCallDepth"); //FIXME hitting VM limits
|
||||||
|
excluded.add("Call10"); //FIXME gaslimit as biginteger
|
||||||
|
excluded.add("createNameRegistratorZeroMem2"); // FIXME: Heap ???
|
||||||
|
String json = JSONReader.loadJSONFromCommit("StateTests/stSystemOperationsTest.json", shacommit);
|
||||||
|
GitHubJSONTestSuite.runStateTest(json, excluded);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void stTransactionTest() throws ParseException, IOException {
|
||||||
|
Set<String> excluded = new HashSet<>();
|
||||||
|
excluded.add("OverflowGasRequire"); //FIXME wont work until we use gaslimit as long
|
||||||
|
excluded.add("EmptyTransaction2"); // Buggy testcase
|
||||||
|
excluded.add("TransactionSendingToEmpty");
|
||||||
|
String json = JSONReader.loadJSONFromCommit("StateTests/stTransactionTest.json", shacommit);
|
||||||
|
GitHubJSONTestSuite.runStateTest(json, excluded);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // testing full suite
|
||||||
|
public void testRandomStateGitHub() throws ParseException, IOException {
|
||||||
|
|
||||||
|
String sha = "99db6f4f5fea3aa5cfbe8436feba8e213d06d1e8";
|
||||||
|
List<String> fileNames = getFileNamesForTreeSha(sha);
|
||||||
|
List<String> includedFiles =
|
||||||
|
Arrays.asList(
|
||||||
|
"st201504081841JAVA.json",
|
||||||
|
"st201504081842JAVA.json",
|
||||||
|
"st201504081843JAVA.json"
|
||||||
|
);
|
||||||
|
|
||||||
|
for (String fileName : fileNames) {
|
||||||
|
if (includedFiles.contains(fileName)) {
|
||||||
|
System.out.println("Running: " + fileName);
|
||||||
|
String json = JSONReader.loadJSON("StateTests//RandomTests/" + fileName);
|
||||||
|
GitHubJSONTestSuite.runStateTest(json);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,168 @@
|
||||||
|
package org.ethereum.jsontestsuite;
|
||||||
|
|
||||||
|
import org.json.simple.parser.ParseException;
|
||||||
|
import org.junit.FixMethodOrder;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runners.MethodSorters;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.ethereum.jsontestsuite.JSONReader.getFileNamesForTreeSha;
|
||||||
|
|
||||||
|
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||||
|
public class GitHubVMTest {
|
||||||
|
|
||||||
|
//SHACOMMIT of tested commit, ethereum/tests.git
|
||||||
|
//Last known good commit: 5af1002b96f34cd2c9252c1a6636826d47411ccd
|
||||||
|
public String shacommit = "5af1002b96f34cd2c9252c1a6636826d47411ccd";
|
||||||
|
|
||||||
|
//@Ignore
|
||||||
|
@Test
|
||||||
|
public void runSingle() throws ParseException {
|
||||||
|
String json = JSONReader.loadJSONFromCommit("VMTests/vmEnvironmentalInfoTest.json", shacommit);
|
||||||
|
GitHubJSONTestSuite.runGitHubJsonVMTest(json, "balance0");
|
||||||
|
}
|
||||||
|
|
||||||
|
//@Ignore
|
||||||
|
@Test
|
||||||
|
public void testArithmeticFromGitHub() throws ParseException {
|
||||||
|
Set<String> excluded = new HashSet<>();
|
||||||
|
// TODO: these are excluded due to bad wrapping behavior in ADDMOD/DataWord.add
|
||||||
|
excluded.add("addmod1_overflowDiff");
|
||||||
|
excluded.add("addmod1_overflow3");
|
||||||
|
excluded.add("addmodBigIntCast");
|
||||||
|
String json = JSONReader.loadJSONFromCommit("VMTests/vmArithmeticTest.json", shacommit);
|
||||||
|
//String json = JSONReader.getTestBlobForTreeSha(shacommit, "vmArithmeticTest.json");
|
||||||
|
GitHubJSONTestSuite.runGitHubJsonVMTest(json, excluded);
|
||||||
|
}
|
||||||
|
|
||||||
|
//@Ignore
|
||||||
|
@Test // testing full suite
|
||||||
|
public void testBitwiseLogicOperationFromGitHub() throws ParseException {
|
||||||
|
Set<String> excluded = new HashSet<>();
|
||||||
|
String json = JSONReader.loadJSONFromCommit("VMTests/vmBitwiseLogicOperationTest.json", shacommit);
|
||||||
|
GitHubJSONTestSuite.runGitHubJsonVMTest(json, excluded);
|
||||||
|
}
|
||||||
|
|
||||||
|
//@Ignore
|
||||||
|
@Test // testing full suite
|
||||||
|
public void testBlockInfoFromGitHub() throws ParseException {
|
||||||
|
Set<String> excluded = new HashSet<>();
|
||||||
|
String json = JSONReader.loadJSONFromCommit("VMTests/vmBlockInfoTest.json", shacommit);
|
||||||
|
GitHubJSONTestSuite.runGitHubJsonVMTest(json, excluded);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Ignore
|
||||||
|
@Test // testing full suite
|
||||||
|
public void testEnvironmentalInfoFromGitHub() throws ParseException {
|
||||||
|
Set<String> excluded = new HashSet<>();
|
||||||
|
excluded.add("env1");
|
||||||
|
String json = JSONReader.loadJSONFromCommit("VMTests/vmEnvironmentalInfoTest.json", shacommit);
|
||||||
|
GitHubJSONTestSuite.runGitHubJsonVMTest(json, excluded);
|
||||||
|
}
|
||||||
|
|
||||||
|
//@Ignore
|
||||||
|
@Test // testing full suite
|
||||||
|
public void testIOandFlowOperationsFromGitHub() throws ParseException {
|
||||||
|
Set<String> excluded = new HashSet<>();
|
||||||
|
String json = JSONReader.loadJSONFromCommit("VMTests/vmIOandFlowOperationsTest.json", shacommit);
|
||||||
|
GitHubJSONTestSuite.runGitHubJsonVMTest(json, excluded);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Ignore //FIXME - 60M - need new fast downloader
|
||||||
|
@Test
|
||||||
|
public void testvmInputLimitsTest1FromGitHub() throws ParseException {
|
||||||
|
Set<String> excluded = new HashSet<>();
|
||||||
|
String json = JSONReader.loadJSONFromCommit("VMTests/vmInputLimits1.json", shacommit);
|
||||||
|
GitHubJSONTestSuite.runGitHubJsonVMTest(json, excluded);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Ignore //FIXME - 50M - need to handle large filesizes
|
||||||
|
@Test
|
||||||
|
public void testvmInputLimitsTest2FromGitHub() throws ParseException {
|
||||||
|
Set<String> excluded = new HashSet<>();
|
||||||
|
String json = JSONReader.loadJSONFromCommit("VMTests/vmInputLimits2.json", shacommit);
|
||||||
|
GitHubJSONTestSuite.runGitHubJsonVMTest(json, excluded);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Ignore //FIXME - 20M - possibly provide percentage indicator
|
||||||
|
@Test
|
||||||
|
public void testvmInputLimitsLightTestFromGitHub() throws ParseException {
|
||||||
|
Set<String> excluded = new HashSet<>();
|
||||||
|
String json = JSONReader.loadJSONFromCommit("VMTests/vmInputLimitsLight.json", shacommit);
|
||||||
|
GitHubJSONTestSuite.runGitHubJsonVMTest(json, excluded);
|
||||||
|
}
|
||||||
|
|
||||||
|
//@Ignore
|
||||||
|
@Test // testing full suite
|
||||||
|
public void testVMLogGitHub() throws ParseException {
|
||||||
|
Set<String> excluded = new HashSet<>();
|
||||||
|
String json = JSONReader.loadJSONFromCommit("VMTests/vmLogTest.json", shacommit);
|
||||||
|
GitHubJSONTestSuite.runGitHubJsonVMTest(json, excluded);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Ignore
|
||||||
|
@Test // testing full suite
|
||||||
|
public void testPerformanceFromGitHub() throws ParseException {
|
||||||
|
Set<String> excluded = new HashSet<>();
|
||||||
|
String json = JSONReader.loadJSONFromCommit("VMTests/vmPerformanceTest.json", shacommit);
|
||||||
|
GitHubJSONTestSuite.runGitHubJsonVMTest(json, excluded);
|
||||||
|
}
|
||||||
|
|
||||||
|
//@Ignore
|
||||||
|
@Test // testing full suite
|
||||||
|
public void testPushDupSwapFromGitHub() throws ParseException {
|
||||||
|
Set<String> excluded = new HashSet<>();
|
||||||
|
String json = JSONReader.loadJSONFromCommit("VMTests/vmPushDupSwapTest.json", shacommit);
|
||||||
|
GitHubJSONTestSuite.runGitHubJsonVMTest(json, excluded);
|
||||||
|
}
|
||||||
|
|
||||||
|
//@Ignore
|
||||||
|
@Test // testing full suite
|
||||||
|
public void testShaFromGitHub() throws ParseException {
|
||||||
|
Set<String> excluded = new HashSet<>();
|
||||||
|
String json = JSONReader.loadJSONFromCommit("VMTests/vmSha3Test.json", shacommit);
|
||||||
|
GitHubJSONTestSuite.runGitHubJsonVMTest(json, excluded);
|
||||||
|
}
|
||||||
|
|
||||||
|
//@Ignore
|
||||||
|
@Test // testing full suite
|
||||||
|
public void testvmSystemOperationsTestGitHub() throws ParseException {
|
||||||
|
Set<String> excluded = new HashSet<>();
|
||||||
|
String json = JSONReader.loadJSONFromCommit("VMTests/vmSystemOperationsTest.json", shacommit);
|
||||||
|
GitHubJSONTestSuite.runGitHubJsonVMTest(json, excluded);
|
||||||
|
}
|
||||||
|
|
||||||
|
//@Ignore
|
||||||
|
@Test // testing full suite
|
||||||
|
public void testVMGitHub() throws ParseException {
|
||||||
|
Set<String> excluded = new HashSet<>();
|
||||||
|
String json = JSONReader.loadJSONFromCommit("VMTests/vmtests.json", shacommit);
|
||||||
|
GitHubJSONTestSuite.runGitHubJsonVMTest(json, excluded);
|
||||||
|
}
|
||||||
|
|
||||||
|
//@Ignore
|
||||||
|
@Test // testing full suite
|
||||||
|
public void testRandomVMGitHub() throws ParseException {
|
||||||
|
|
||||||
|
String sha = "c5eafb85390eee59b838a93ae31bc16a5fd4f7b1";
|
||||||
|
List<String> fileNames = getFileNamesForTreeSha(sha);
|
||||||
|
List<String> excludedFiles =
|
||||||
|
Arrays.asList(
|
||||||
|
""
|
||||||
|
);
|
||||||
|
|
||||||
|
for (String fileName : fileNames) {
|
||||||
|
|
||||||
|
if (excludedFiles.contains(fileName)) continue;
|
||||||
|
System.out.println("Running: " + fileName);
|
||||||
|
String json = JSONReader.loadJSON("VMTests//RandomTests/" + fileName);
|
||||||
|
GitHubJSONTestSuite.runGitHubJsonVMTest(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,52 @@
|
||||||
|
package org.ethereum.net;
|
||||||
|
|
||||||
|
import org.ethereum.core.Block;
|
||||||
|
import org.ethereum.net.eth.BlocksMessage;
|
||||||
|
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
import java.nio.file.Files;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
@Ignore
|
||||||
|
public class BlocksMessageTest {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger("test");
|
||||||
|
|
||||||
|
/* BLOCKS */
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_1() {
|
||||||
|
|
||||||
|
byte[] payload = Hex.decode("f901fff901fcf901f7a0fbce9f78142b5d76c2787d89d574136573f62dce21dd7bcf27c7c68ab407ccc3a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479415caa04a9407a2f242b2859005a379655bfb9b11a0689e7e862856d619e32ec5d949711164b447e0df7e55f4570d9fa27f33ca31a2a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830201c008832fefd880845504456b80a05b0400eac058e0243754f4149f14e5c84cef1c33a79d83e21c80f590b953fd60881b4ef00c7a4dae1fc0c0");
|
||||||
|
|
||||||
|
BlocksMessage blocksMessage = new BlocksMessage(payload);
|
||||||
|
List<Block> list = blocksMessage.getBlocks();
|
||||||
|
logger.info(blocksMessage.toString());
|
||||||
|
|
||||||
|
Block block = list.get(0);
|
||||||
|
assertEquals(0, block.getTransactionsList().size());
|
||||||
|
assertEquals(8, block.getNumber());
|
||||||
|
assertEquals("2bff4626b9854e88c72ccc5b47621a0a4e47ef5d97e1fa7c00560f7cd57543c5",
|
||||||
|
Hex.toHexString(block.getHash()));
|
||||||
|
assertEquals("689e7e862856d619e32ec5d949711164b447e0df7e55f4570d9fa27f33ca31a2",
|
||||||
|
Hex.toHexString(block.getStateRoot()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
package org.ethereum.net;
|
||||||
|
|
||||||
|
import org.ethereum.net.message.ReasonCode;
|
||||||
|
import org.ethereum.net.p2p.DisconnectMessage;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
public class DisconnectMessageTest {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger("test");
|
||||||
|
|
||||||
|
/* DISCONNECT_MESSAGE */
|
||||||
|
|
||||||
|
@Test /* DisconnectMessage 1 - Requested */
|
||||||
|
public void test_1() {
|
||||||
|
|
||||||
|
byte[] payload = Hex.decode("C100");
|
||||||
|
DisconnectMessage disconnectMessage = new DisconnectMessage(payload);
|
||||||
|
|
||||||
|
logger.trace("{}" + disconnectMessage);
|
||||||
|
assertEquals(disconnectMessage.getReason(), ReasonCode.REQUESTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test /* DisconnectMessage 2 - TCP Error */
|
||||||
|
public void test_2() {
|
||||||
|
|
||||||
|
byte[] payload = Hex.decode("C101");
|
||||||
|
DisconnectMessage disconnectMessage = new DisconnectMessage(payload);
|
||||||
|
|
||||||
|
logger.trace("{}" + disconnectMessage);
|
||||||
|
assertEquals(disconnectMessage.getReason(), ReasonCode.TCP_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test /* DisconnectMessage 2 - from constructor */
|
||||||
|
public void test_3() {
|
||||||
|
|
||||||
|
DisconnectMessage disconnectMessage = new DisconnectMessage(ReasonCode.NULL_IDENTITY);
|
||||||
|
|
||||||
|
logger.trace("{}" + disconnectMessage);
|
||||||
|
|
||||||
|
String expected = "c107";
|
||||||
|
assertEquals(expected, Hex.toHexString(disconnectMessage.getEncoded()));
|
||||||
|
|
||||||
|
assertEquals(ReasonCode.NULL_IDENTITY, disconnectMessage.getReason());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test //handling boundary-high
|
||||||
|
public void test_4() {
|
||||||
|
|
||||||
|
byte[] payload = Hex.decode("C180");
|
||||||
|
|
||||||
|
DisconnectMessage disconnectMessage = new DisconnectMessage(payload);
|
||||||
|
logger.trace("{}" + disconnectMessage);
|
||||||
|
|
||||||
|
assertEquals(disconnectMessage.getReason(), ReasonCode.REQUESTED); //high numbers are zeroed
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test //handling boundary-low minus 1 (error)
|
||||||
|
public void test_6() {
|
||||||
|
|
||||||
|
String disconnectMessageRaw = "C19999";
|
||||||
|
byte[] payload = Hex.decode(disconnectMessageRaw);
|
||||||
|
|
||||||
|
try {
|
||||||
|
DisconnectMessage disconnectMessage = new DisconnectMessage(payload);
|
||||||
|
disconnectMessage.toString(); //throws exception
|
||||||
|
assertTrue("Valid raw encoding for disconnectMessage", false);
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
assertTrue("Invalid raw encoding for disconnectMessage", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test //handling boundary-high plus 1 (error)
|
||||||
|
public void test_7() {
|
||||||
|
|
||||||
|
String disconnectMessageRaw = "C28081";
|
||||||
|
byte[] payload = Hex.decode(disconnectMessageRaw);
|
||||||
|
|
||||||
|
try {
|
||||||
|
DisconnectMessage disconnectMessage = new DisconnectMessage(payload);
|
||||||
|
disconnectMessage.toString(); //throws exception
|
||||||
|
assertTrue("Valid raw encoding for disconnectMessage", false);
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
assertTrue("Invalid raw encoding for disconnectMessage", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
package org.ethereum.net;
|
||||||
|
|
||||||
|
import org.ethereum.net.eth.BlockHashesMessage;
|
||||||
|
import org.ethereum.net.eth.EthMessageCodes;
|
||||||
|
import org.ethereum.net.eth.GetBlockHashesMessage;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class GetBlockHashesMessageTest {
|
||||||
|
|
||||||
|
/* BLOCK_HASHES_MESSAGE */
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger("test");
|
||||||
|
|
||||||
|
|
||||||
|
@Test /* BlockHashesMessage 1 from network */
|
||||||
|
public void test_1() {
|
||||||
|
String blockHashesMessageRaw = "e4a05ad1c9caeade4cdf5798e796dc87939231d9c76c20a6a33fea6dab8e9d6dd009820100";
|
||||||
|
|
||||||
|
byte[] payload = Hex.decode(blockHashesMessageRaw);
|
||||||
|
GetBlockHashesMessage getBlockHashesMessage = new GetBlockHashesMessage(payload);
|
||||||
|
System.out.println(getBlockHashesMessage);
|
||||||
|
|
||||||
|
assertEquals(EthMessageCodes.GET_BLOCK_HASHES, getBlockHashesMessage.getCommand());
|
||||||
|
assertEquals("5ad1c9caeade4cdf5798e796dc87939231d9c76c20a6a33fea6dab8e9d6dd009", Hex.toHexString(getBlockHashesMessage.getBestHash()));
|
||||||
|
assertEquals(256, getBlockHashesMessage.getMaxBlocks());
|
||||||
|
assertEquals(BlockHashesMessage.class, getBlockHashesMessage.getAnswerMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
package org.ethereum.net;
|
||||||
|
|
||||||
|
import org.ethereum.net.eth.BlocksMessage;
|
||||||
|
import org.ethereum.net.eth.EthMessageCodes;
|
||||||
|
import org.ethereum.net.eth.GetBlocksMessage;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class GetBlocksMessageTest {
|
||||||
|
|
||||||
|
/* GET_BLOCKS */
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger("test");
|
||||||
|
|
||||||
|
|
||||||
|
@Test /* GetBlocks message parsing */
|
||||||
|
public void test_1() {
|
||||||
|
|
||||||
|
byte[] payload = Hex.decode("f8a5a0497dcbd12fa99ced7b27cda6611f64eb13ab50e20260eec5ee6b7190e7206d54a00959bdfba5e54fcc9370e86b7996fbe32a277bab65c31a0102226f83c4d3e0f2a001a333c156485880776e929e84c26c9778c1e9b4dcb5cd3bff8ad0aeff385df0a0690e13595c9e8e4fa9a621dfed6ad828a6e8e591479af6897c979a83daf73084a0b20f253d2b62609e932c13f3bca59a22913ea5b1e532d8a707976997461ec143");
|
||||||
|
GetBlocksMessage getBlocksMessage = new GetBlocksMessage(payload);
|
||||||
|
System.out.println(getBlocksMessage);
|
||||||
|
|
||||||
|
assertEquals(EthMessageCodes.GET_BLOCKS, getBlocksMessage.getCommand());
|
||||||
|
assertEquals(5, getBlocksMessage.getBlockHashes().size());
|
||||||
|
String hash1 = "497dcbd12fa99ced7b27cda6611f64eb13ab50e20260eec5ee6b7190e7206d54";
|
||||||
|
String hash4 = "b20f253d2b62609e932c13f3bca59a22913ea5b1e532d8a707976997461ec143";
|
||||||
|
assertEquals(hash1, Hex.toHexString(getBlocksMessage.getBlockHashes().get(0)));
|
||||||
|
assertEquals(hash4, Hex.toHexString(getBlocksMessage.getBlockHashes().get(4)));
|
||||||
|
|
||||||
|
assertEquals(BlocksMessage.class, getBlocksMessage.getAnswerMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,94 @@
|
||||||
|
package org.ethereum.net;
|
||||||
|
|
||||||
|
import org.ethereum.net.client.Capability;
|
||||||
|
import org.ethereum.net.eth.EthHandler;
|
||||||
|
import org.ethereum.net.p2p.HelloMessage;
|
||||||
|
import org.ethereum.net.p2p.P2pHandler;
|
||||||
|
import org.ethereum.net.p2p.P2pMessageCodes;
|
||||||
|
import org.ethereum.net.shh.ShhHandler;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class HelloMessageTest {
|
||||||
|
|
||||||
|
/* HELLO_MESSAGE */
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger("test");
|
||||||
|
|
||||||
|
//Parsing from raw bytes
|
||||||
|
@Test
|
||||||
|
public void test1() {
|
||||||
|
String helloMessageRaw = "f87902a5457468657265756d282b2b292f76302e372e392f52656c656173652f4c696e75782f672b2bccc58365746827c583736868018203e0b8401fbf1e41f08078918c9f7b6734594ee56d7f538614f602c71194db0a1af5a77f9b86eb14669fe7a8a46a2dd1b7d070b94e463f4ecd5b337c8b4d31bbf8dd5646";
|
||||||
|
|
||||||
|
byte[] payload = Hex.decode(helloMessageRaw);
|
||||||
|
HelloMessage helloMessage = new HelloMessage(payload);
|
||||||
|
logger.info(helloMessage.toString());
|
||||||
|
|
||||||
|
assertEquals(P2pMessageCodes.HELLO, helloMessage.getCommand());
|
||||||
|
assertEquals(2, helloMessage.getP2PVersion());
|
||||||
|
assertEquals("Ethereum(++)/v0.7.9/Release/Linux/g++", helloMessage.getClientId());
|
||||||
|
assertEquals(2, helloMessage.getCapabilities().size());
|
||||||
|
assertEquals(992, helloMessage.getListenPort());
|
||||||
|
assertEquals(
|
||||||
|
"1fbf1e41f08078918c9f7b6734594ee56d7f538614f602c71194db0a1af5a77f9b86eb14669fe7a8a46a2dd1b7d070b94e463f4ecd5b337c8b4d31bbf8dd5646",
|
||||||
|
helloMessage.getPeerId());
|
||||||
|
}
|
||||||
|
|
||||||
|
//Instantiate from constructor
|
||||||
|
@Test
|
||||||
|
public void test2() {
|
||||||
|
|
||||||
|
//Init
|
||||||
|
byte version = 2;
|
||||||
|
String clientStr = "Ethereum(++)/v0.7.9/Release/Linux/g++";
|
||||||
|
List<Capability> capabilities = Arrays.asList(
|
||||||
|
new Capability(Capability.ETH, EthHandler.VERSION),
|
||||||
|
new Capability(Capability.SHH, ShhHandler.VERSION),
|
||||||
|
new Capability(Capability.P2P, P2pHandler.VERSION));
|
||||||
|
int listenPort = 992;
|
||||||
|
String peerId = "1fbf1e41f08078918c9f7b6734594ee56d7f538614f602c71194db0a1af5a";
|
||||||
|
|
||||||
|
HelloMessage helloMessage = new HelloMessage(version, clientStr, capabilities, listenPort, peerId);
|
||||||
|
logger.info(helloMessage.toString());
|
||||||
|
|
||||||
|
assertEquals(P2pMessageCodes.HELLO, helloMessage.getCommand());
|
||||||
|
assertEquals(version, helloMessage.getP2PVersion());
|
||||||
|
assertEquals(clientStr, helloMessage.getClientId());
|
||||||
|
assertEquals(3, helloMessage.getCapabilities().size());
|
||||||
|
assertEquals(listenPort, helloMessage.getListenPort());
|
||||||
|
assertEquals(peerId, helloMessage.getPeerId());
|
||||||
|
}
|
||||||
|
|
||||||
|
//Fail test
|
||||||
|
@Test
|
||||||
|
public void test3() {
|
||||||
|
//Init
|
||||||
|
byte version = -1; //invalid version
|
||||||
|
String clientStr = ""; //null id
|
||||||
|
List<Capability> capabilities = Arrays.asList(
|
||||||
|
new Capability(null, (byte) 0),
|
||||||
|
new Capability(null, (byte) 0),
|
||||||
|
null, //null here causes NullPointerException when using toString
|
||||||
|
new Capability(null, (byte) 0)); //encoding null capabilities
|
||||||
|
int listenPort = 99999; //invalid port
|
||||||
|
String peerId = ""; //null id
|
||||||
|
|
||||||
|
HelloMessage helloMessage = new HelloMessage(version, clientStr, capabilities, listenPort, peerId);
|
||||||
|
|
||||||
|
assertEquals(P2pMessageCodes.HELLO, helloMessage.getCommand());
|
||||||
|
assertEquals(version, helloMessage.getP2PVersion());
|
||||||
|
assertEquals(clientStr, helloMessage.getClientId());
|
||||||
|
assertEquals(4, helloMessage.getCapabilities().size());
|
||||||
|
assertEquals(listenPort, helloMessage.getListenPort());
|
||||||
|
assertEquals(peerId, helloMessage.getPeerId());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package org.ethereum.net;
|
||||||
|
|
||||||
|
import org.ethereum.core.Block;
|
||||||
|
import org.ethereum.net.eth.NewBlockMessage;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
public class NewBlockMessageTest {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger("test");
|
||||||
|
|
||||||
|
|
||||||
|
/* NEW_BLOCK */
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_1() {
|
||||||
|
|
||||||
|
byte[] payload = Hex.decode("f90144f9013Bf90136a0d8faffbc4c4213d35db9007de41cece45d95db7fd6c0f129e158baa888c48eefa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794baedba0480e1b882b606cd302d8c4f5701cabac7a0c7d4565fb7b3d98e54a0dec8b76f8c001a784a5689954ce0aedcc1bbe8d13095a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b8400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083063477825fc88609184e72a0008301e8488084543ffee680a00de0b9d4a0f0c23546d31f1f70db00d25cf6a7af79365b4e058e4a6a3b69527bc0c0850177ddbebe");
|
||||||
|
|
||||||
|
NewBlockMessage newBlockMessage = new NewBlockMessage(payload);
|
||||||
|
logger.trace("{}", newBlockMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
package org.ethereum.net;
|
||||||
|
|
||||||
|
import org.ethereum.net.client.Capability;
|
||||||
|
import org.ethereum.net.p2p.Peer;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class PeerTest {
|
||||||
|
|
||||||
|
/* PEER */
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPeer() {
|
||||||
|
|
||||||
|
//Init
|
||||||
|
InetAddress address = InetAddress.getLoopbackAddress();
|
||||||
|
List<Capability> capabilities = new ArrayList<>();
|
||||||
|
int port = 1010;
|
||||||
|
String peerId = "1010";
|
||||||
|
Peer peerCopy = new Peer(address, port, peerId);
|
||||||
|
|
||||||
|
//Peer
|
||||||
|
Peer peer = new Peer(address, port, peerId);
|
||||||
|
|
||||||
|
//getAddress
|
||||||
|
assertEquals("127.0.0.1", peer.getAddress().getHostAddress());
|
||||||
|
|
||||||
|
//getPort
|
||||||
|
assertEquals(port, peer.getPort());
|
||||||
|
|
||||||
|
//getPeerId
|
||||||
|
assertEquals(peerId, peer.getPeerId());
|
||||||
|
|
||||||
|
//getCapabilities
|
||||||
|
assertEquals(capabilities, peer.getCapabilities());
|
||||||
|
|
||||||
|
//getEncoded
|
||||||
|
assertEquals("CC847F0000018203F2821010C0", Hex.toHexString(peer.getEncoded()).toUpperCase());
|
||||||
|
|
||||||
|
//toString
|
||||||
|
assertEquals("[ip=" + address.getHostAddress() + " port=" + Integer.toString(port) + " peerId=" + peerId + "]", peer.toString());
|
||||||
|
|
||||||
|
//equals
|
||||||
|
assertEquals(true, peer.equals(peerCopy));
|
||||||
|
assertEquals(false, peer.equals(null));
|
||||||
|
|
||||||
|
//hashCode
|
||||||
|
assertEquals(-1, peer.hashCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
package org.ethereum.net;
|
||||||
|
|
||||||
|
import org.ethereum.net.p2p.P2pMessageCodes;
|
||||||
|
import org.ethereum.net.p2p.PingMessage;
|
||||||
|
import org.ethereum.net.p2p.PongMessage;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class PingPongMessageTest {
|
||||||
|
|
||||||
|
/* PING_MESSAGE & PONG_MESSAGE */
|
||||||
|
|
||||||
|
@Test /* PingMessage */
|
||||||
|
public void testPing() {
|
||||||
|
|
||||||
|
PingMessage pingMessage = new PingMessage();
|
||||||
|
System.out.println(pingMessage);
|
||||||
|
|
||||||
|
assertEquals(PongMessage.class, pingMessage.getAnswerMessage());
|
||||||
|
|
||||||
|
assertEquals(P2pMessageCodes.PING, pingMessage.getCommand());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test /* PongMessage */
|
||||||
|
public void testPong() {
|
||||||
|
|
||||||
|
PongMessage pongMessage = new PongMessage();
|
||||||
|
System.out.println(pongMessage);
|
||||||
|
|
||||||
|
assertEquals(P2pMessageCodes.PONG, pongMessage.getCommand());
|
||||||
|
assertEquals(null, pongMessage.getAnswerMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
package org.ethereum.net;
|
||||||
|
|
||||||
|
import org.ethereum.net.eth.StatusMessage;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class StatusMessageTest {
|
||||||
|
|
||||||
|
/* STATUS_MESSAGE */
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger("test");
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test1() {
|
||||||
|
|
||||||
|
byte[] payload = Hex.decode("f84927808425c60144a0832056d3c93ff2739ace7199952e5365aa29f18805be05634c4db125c5340216a0955f36d073ccb026b78ab3424c15cf966a7563aa270413859f78702b9e8e22cb");
|
||||||
|
StatusMessage statusMessage = new StatusMessage(payload);
|
||||||
|
|
||||||
|
logger.info(statusMessage.toString());
|
||||||
|
|
||||||
|
assertEquals(39, statusMessage.getProtocolVersion());
|
||||||
|
assertEquals("25c60144",
|
||||||
|
Hex.toHexString(statusMessage.getTotalDifficulty()));
|
||||||
|
assertEquals("832056d3c93ff2739ace7199952e5365aa29f18805be05634c4db125c5340216",
|
||||||
|
Hex.toHexString(statusMessage.getBestHash()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,200 @@
|
||||||
|
package org.ethereum.net;
|
||||||
|
|
||||||
|
import org.ethereum.core.Transaction;
|
||||||
|
import org.ethereum.crypto.ECKey;
|
||||||
|
import org.ethereum.crypto.HashUtil;
|
||||||
|
import org.ethereum.net.eth.EthMessageCodes;
|
||||||
|
import org.ethereum.net.eth.GetTransactionsMessage;
|
||||||
|
import org.ethereum.net.eth.TransactionsMessage;
|
||||||
|
import org.ethereum.util.ByteUtil;
|
||||||
|
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
public class TransactionsMessageTest {
|
||||||
|
|
||||||
|
/* GET_TRANSACTIONS */
|
||||||
|
|
||||||
|
@Test /* GetTransactions message 1 */
|
||||||
|
public void testGetTransactions() {
|
||||||
|
|
||||||
|
GetTransactionsMessage getTransactionsMessage = new GetTransactionsMessage();
|
||||||
|
System.out.println(getTransactionsMessage);
|
||||||
|
|
||||||
|
assertEquals(EthMessageCodes.GET_TRANSACTIONS, getTransactionsMessage.getCommand());
|
||||||
|
assertEquals(TransactionsMessage.class, getTransactionsMessage.getAnswerMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TRANSACTIONS */
|
||||||
|
|
||||||
|
@Ignore
|
||||||
|
@Test /* Transactions message 1 */
|
||||||
|
public void test_1() {
|
||||||
|
|
||||||
|
String txsPacketRaw = "f86e12f86b04648609184e72a00094cd2a3d9f938e13cd947ec05abc7fe734df8dd826"
|
||||||
|
+ "881bc16d674ec80000801ba05c89ebf2b77eeab88251e553f6f9d53badc1d800"
|
||||||
|
+ "bbac02d830801c2aa94a4c9fa00b7907532b1f29c79942b75fff98822293bf5f"
|
||||||
|
+ "daa3653a8d9f424c6a3265f06c";
|
||||||
|
|
||||||
|
byte[] payload = Hex.decode(txsPacketRaw);
|
||||||
|
|
||||||
|
TransactionsMessage transactionsMessage = new TransactionsMessage(payload);
|
||||||
|
System.out.println(transactionsMessage);
|
||||||
|
|
||||||
|
assertEquals(EthMessageCodes.TRANSACTIONS, transactionsMessage.getCommand());
|
||||||
|
assertEquals(1, transactionsMessage.getTransactions().size());
|
||||||
|
|
||||||
|
Transaction tx = transactionsMessage.getTransactions().iterator().next();
|
||||||
|
|
||||||
|
assertEquals("5d2aee0490a9228024158433d650335116b4af5a30b8abb10e9b7f9f7e090fd8", Hex.toHexString(tx.getHash()));
|
||||||
|
assertEquals("04", Hex.toHexString(tx.getNonce()));
|
||||||
|
assertEquals("1bc16d674ec80000", Hex.toHexString(tx.getValue()));
|
||||||
|
assertEquals("cd2a3d9f938e13cd947ec05abc7fe734df8dd826", Hex.toHexString(tx.getReceiveAddress()));
|
||||||
|
assertEquals("64", Hex.toHexString(tx.getGasPrice()));
|
||||||
|
assertEquals("09184e72a000", Hex.toHexString(tx.getGasLimit()));
|
||||||
|
assertEquals("", ByteUtil.toHexString(tx.getData()));
|
||||||
|
|
||||||
|
assertEquals("1b", Hex.toHexString(new byte[]{tx.getSignature().v}));
|
||||||
|
assertEquals("5c89ebf2b77eeab88251e553f6f9d53badc1d800bbac02d830801c2aa94a4c9f", Hex.toHexString(tx.getSignature().r.toByteArray()));
|
||||||
|
assertEquals("0b7907532b1f29c79942b75fff98822293bf5fdaa3653a8d9f424c6a3265f06c", Hex.toHexString(tx.getSignature().s.toByteArray()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Ignore
|
||||||
|
@Test /* Transactions message 2 */
|
||||||
|
public void test_2() {
|
||||||
|
|
||||||
|
String txsPacketRaw = "f9025012f89d8080940000000000000000000000000000000000000000860918"
|
||||||
|
+ "4e72a000822710b3606956330c0d630000003359366000530a0d630000003359"
|
||||||
|
+ "602060005301356000533557604060005301600054630000000c588433606957"
|
||||||
|
+ "1ca07f6eb94576346488c6253197bde6a7e59ddc36f2773672c849402aa9c402"
|
||||||
|
+ "c3c4a06d254e662bf7450dd8d835160cbb053463fed0b53f2cdd7f3ea8731919"
|
||||||
|
+ "c8e8ccf901050180940000000000000000000000000000000000000000860918"
|
||||||
|
+ "4e72a000822710b85336630000002e59606956330c0d63000000155933ff3356"
|
||||||
|
+ "0d63000000275960003356576000335700630000005358600035560d63000000"
|
||||||
|
+ "3a590033560d63000000485960003356573360003557600035335700b84a7f4e"
|
||||||
|
+ "616d655265670000000000000000000000000000000000000000000000000030"
|
||||||
|
+ "57307f4e616d6552656700000000000000000000000000000000000000000000"
|
||||||
|
+ "00000057336069571ba04af15a0ec494aeac5b243c8a2690833faa74c0f73db1"
|
||||||
|
+ "f439d521c49c381513e9a05802e64939be5a1f9d4d614038fbd5479538c48795"
|
||||||
|
+ "614ef9c551477ecbdb49d2f8a6028094ccdeac59d35627b7de09332e819d5159"
|
||||||
|
+ "e7bb72508609184e72a000822710b84000000000000000000000000000000000"
|
||||||
|
+ "000000000000000000000000000000000000000000000000000000002d0aceee"
|
||||||
|
+ "7e5ab874e22ccf8d1a649f59106d74e81ba0d05887574456c6de8f7a0d172342"
|
||||||
|
+ "c2cbdd4cf7afe15d9dbb8b75b748ba6791c9a01e87172a861f6c37b5a9e3a5d0"
|
||||||
|
+ "d7393152a7fbe41530e5bb8ac8f35433e5931b";
|
||||||
|
|
||||||
|
byte[] payload = Hex.decode(txsPacketRaw);
|
||||||
|
|
||||||
|
TransactionsMessage transactionsMessage = new TransactionsMessage(payload);
|
||||||
|
System.out.println(transactionsMessage);
|
||||||
|
|
||||||
|
assertEquals(EthMessageCodes.TRANSACTIONS, transactionsMessage.getCommand());
|
||||||
|
|
||||||
|
assertEquals(3, transactionsMessage.getTransactions().size());
|
||||||
|
|
||||||
|
Iterator<Transaction> txIter = transactionsMessage.getTransactions().iterator();
|
||||||
|
Transaction tx1 = txIter.next();
|
||||||
|
txIter.next(); // skip one
|
||||||
|
Transaction tx3 = txIter.next();
|
||||||
|
|
||||||
|
assertEquals("1b9d9456293cbcbc2f28a0fdc67028128ea571b033fb0e21d0ee00bcd6167e5d",
|
||||||
|
Hex.toHexString(tx3.getHash()));
|
||||||
|
|
||||||
|
assertEquals("00",
|
||||||
|
Hex.toHexString(tx3.getNonce()));
|
||||||
|
|
||||||
|
assertEquals("2710",
|
||||||
|
Hex.toHexString(tx3.getValue()));
|
||||||
|
|
||||||
|
assertEquals("09184e72a000",
|
||||||
|
Hex.toHexString(tx3.getReceiveAddress()));
|
||||||
|
|
||||||
|
assertNull(tx3.getGasPrice());
|
||||||
|
|
||||||
|
assertEquals("0000000000000000000000000000000000000000",
|
||||||
|
Hex.toHexString(tx3.getGasLimit()));
|
||||||
|
|
||||||
|
assertEquals("606956330c0d630000003359366000530a0d630000003359602060005301356000533557604060005301600054630000000c58",
|
||||||
|
Hex.toHexString(tx3.getData()));
|
||||||
|
|
||||||
|
assertEquals("33",
|
||||||
|
Hex.toHexString(new byte[]{tx3.getSignature().v}));
|
||||||
|
|
||||||
|
assertEquals("1c",
|
||||||
|
Hex.toHexString(tx3.getSignature().r.toByteArray()));
|
||||||
|
|
||||||
|
assertEquals("7f6eb94576346488c6253197bde6a7e59ddc36f2773672c849402aa9c402c3c4",
|
||||||
|
Hex.toHexString(tx3.getSignature().s.toByteArray()));
|
||||||
|
|
||||||
|
// Transaction #2
|
||||||
|
|
||||||
|
assertEquals("dde9543921850f41ca88e5401322cd7651c78a1e4deebd5ee385af8ac343f0ad",
|
||||||
|
Hex.toHexString(tx1.getHash()));
|
||||||
|
|
||||||
|
assertEquals("02",
|
||||||
|
Hex.toHexString(tx1.getNonce()));
|
||||||
|
|
||||||
|
assertEquals("2710",
|
||||||
|
Hex.toHexString(tx1.getValue()));
|
||||||
|
|
||||||
|
assertEquals("09184e72a000",
|
||||||
|
Hex.toHexString(tx1.getReceiveAddress()));
|
||||||
|
|
||||||
|
assertNull(tx1.getGasPrice());
|
||||||
|
|
||||||
|
assertEquals("ccdeac59d35627b7de09332e819d5159e7bb7250",
|
||||||
|
Hex.toHexString(tx1.getGasLimit()));
|
||||||
|
|
||||||
|
assertEquals
|
||||||
|
("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000002d0aceee7e5ab874e22ccf8d1a649f59106d74e8",
|
||||||
|
Hex.toHexString(tx1.getData()));
|
||||||
|
|
||||||
|
assertEquals("1b",
|
||||||
|
Hex.toHexString(new byte[]{tx1.getSignature().v}));
|
||||||
|
|
||||||
|
assertEquals("00d05887574456c6de8f7a0d172342c2cbdd4cf7afe15d9dbb8b75b748ba6791c9",
|
||||||
|
Hex.toHexString(tx1.getSignature().r.toByteArray()));
|
||||||
|
|
||||||
|
assertEquals("1e87172a861f6c37b5a9e3a5d0d7393152a7fbe41530e5bb8ac8f35433e5931b",
|
||||||
|
Hex.toHexString(tx1.getSignature().s.toByteArray()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test /* Transactions msg encode */
|
||||||
|
public void test_3() throws Exception {
|
||||||
|
|
||||||
|
String expected =
|
||||||
|
"f87302f870808b00d3c21bcecceda10000009479b08ad8787060333663d19704909ee7b1903e588609184e72a000824255801ca00f410a70e42b2c9854a8421d32c87c370a2b9fff0a27f9f031bb4443681d73b5a018a7dc4c4f9dee9f3dc35cb96ca15859aa27e219a8e4a8547be6bd3206979858";
|
||||||
|
|
||||||
|
BigInteger value = new BigInteger("1000000000000000000000000");
|
||||||
|
|
||||||
|
byte[] privKey = HashUtil.sha3("cat".getBytes());
|
||||||
|
ECKey ecKey = ECKey.fromPrivate(privKey);
|
||||||
|
|
||||||
|
byte[] gasPrice = Hex.decode("09184e72a000");
|
||||||
|
byte[] gas = Hex.decode("4255");
|
||||||
|
|
||||||
|
Transaction tx = new Transaction(null, value.toByteArray(),
|
||||||
|
ecKey.getAddress(), gasPrice, gas, null);
|
||||||
|
|
||||||
|
tx.sign(privKey);
|
||||||
|
tx.getEncoded();
|
||||||
|
|
||||||
|
Set<Transaction> txs = new HashSet<>(Arrays.asList(tx));
|
||||||
|
TransactionsMessage transactionsMessage = new TransactionsMessage(txs);
|
||||||
|
|
||||||
|
assertEquals(EthMessageCodes.TRANSACTIONS, transactionsMessage.getCommand());
|
||||||
|
assertEquals(expected, Hex.toHexString(transactionsMessage.getEncoded()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
package org.ethereum.net.rlpx;
|
||||||
|
|
||||||
|
import org.ethereum.crypto.ECKey;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by android on 4/8/15.
|
||||||
|
*/
|
||||||
|
public class EncryptionHandshakeTest {
|
||||||
|
private ECKey myKey;
|
||||||
|
private ECKey remoteKey;
|
||||||
|
private EncryptionHandshake initiator;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
remoteKey = new ECKey().decompress();
|
||||||
|
myKey = new ECKey().decompress();
|
||||||
|
initiator = new EncryptionHandshake(remoteKey.getPubKeyPoint());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateAuthInitiate() throws Exception {
|
||||||
|
AuthInitiateMessage message = initiator.createAuthInitiate(new byte[32], myKey);
|
||||||
|
int expectedLength = 65+32+64+32+1;
|
||||||
|
byte[] buffer = message.encode();
|
||||||
|
assertEquals(expectedLength, buffer.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAgreement() throws Exception {
|
||||||
|
EncryptionHandshake responder = new EncryptionHandshake();
|
||||||
|
AuthInitiateMessage initiate = initiator.createAuthInitiate(null, myKey);
|
||||||
|
byte[] initiatePacket = initiator.encryptAuthMessage(initiate);
|
||||||
|
byte[] responsePacket = responder.handleAuthInitiate(initiatePacket, remoteKey);
|
||||||
|
initiator.handleAuthResponse(myKey, initiatePacket, responsePacket);
|
||||||
|
assertArrayEquals(initiator.getSecrets().aes, responder.getSecrets().aes);
|
||||||
|
assertArrayEquals(initiator.getSecrets().mac, responder.getSecrets().mac);
|
||||||
|
assertArrayEquals(initiator.getSecrets().token, responder.getSecrets().token);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,249 @@
|
||||||
|
package org.ethereum.net.rlpx;
|
||||||
|
|
||||||
|
import org.ethereum.crypto.ECKey;
|
||||||
|
import org.ethereum.net.rlpx.*;
|
||||||
|
import org.ethereum.util.RLP;
|
||||||
|
import org.ethereum.util.RLPList;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import static org.ethereum.crypto.HashUtil.sha3;
|
||||||
|
import static org.ethereum.util.ByteUtil.merge;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
public class RLPXTest {
|
||||||
|
|
||||||
|
private static final org.slf4j.Logger logger = LoggerFactory.getLogger("test");
|
||||||
|
|
||||||
|
@Test // ping test
|
||||||
|
public void test1() {
|
||||||
|
|
||||||
|
String ip = "85.65.19.231";
|
||||||
|
int port = 30303;
|
||||||
|
ECKey key = ECKey.fromPrivate(BigInteger.TEN);
|
||||||
|
|
||||||
|
Message ping = PingMessage.create(ip, port, key);
|
||||||
|
logger.info("{}", ping);
|
||||||
|
|
||||||
|
byte[] wire = ping.getPacket();
|
||||||
|
PingMessage ping2 = (PingMessage) Message.decode(wire);
|
||||||
|
logger.info("{}", ping2);
|
||||||
|
|
||||||
|
assertEquals(ping.toString(), ping2.toString());
|
||||||
|
|
||||||
|
String key2 = ping2.getKey().toString();
|
||||||
|
assertEquals(key.toString(), key2.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Ignore
|
||||||
|
@Test // pong test
|
||||||
|
public void test2() {
|
||||||
|
|
||||||
|
byte[] token = sha3("+++".getBytes(Charset.forName("UTF-8")));
|
||||||
|
ECKey key = ECKey.fromPrivate(BigInteger.TEN);
|
||||||
|
|
||||||
|
Message pong = PongMessage.create(token, key);
|
||||||
|
logger.info("{}", pong);
|
||||||
|
|
||||||
|
byte[] wire = pong.getPacket();
|
||||||
|
PongMessage pong2 = (PongMessage) Message.decode(wire);
|
||||||
|
logger.info("{}", pong);
|
||||||
|
|
||||||
|
assertEquals(pong.toString(), pong2.toString());
|
||||||
|
|
||||||
|
String key2 = pong2.getKey().toString();
|
||||||
|
assertEquals(key.toString(), key2.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // neighbors message
|
||||||
|
public void test3() {
|
||||||
|
|
||||||
|
String ip = "85.65.19.231";
|
||||||
|
int port = 30303;
|
||||||
|
|
||||||
|
byte[] part1 = sha3("007".getBytes(Charset.forName("UTF-8")));
|
||||||
|
byte[] part2 = sha3("007".getBytes(Charset.forName("UTF-8")));
|
||||||
|
byte[] id = merge(part1, part2);
|
||||||
|
|
||||||
|
Node node = new Node(id, ip, port);
|
||||||
|
|
||||||
|
List<Node> nodes = Arrays.asList(node);
|
||||||
|
ECKey key = ECKey.fromPrivate(BigInteger.TEN);
|
||||||
|
|
||||||
|
Message neighbors = NeighborsMessage.create(nodes, key);
|
||||||
|
logger.info("{}", neighbors);
|
||||||
|
|
||||||
|
byte[] wire = neighbors.getPacket();
|
||||||
|
NeighborsMessage neighbors2 = (NeighborsMessage) Message.decode(wire);
|
||||||
|
logger.info("{}", neighbors2);
|
||||||
|
|
||||||
|
assertEquals(neighbors.toString(), neighbors2.toString());
|
||||||
|
|
||||||
|
String key2 = neighbors2.getKey().toString();
|
||||||
|
assertEquals(key.toString(), key2.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Ignore
|
||||||
|
@Test // find node message
|
||||||
|
public void test4() {
|
||||||
|
|
||||||
|
byte[] id = sha3("+++".getBytes(Charset.forName("UTF-8")));
|
||||||
|
ECKey key = ECKey.fromPrivate(BigInteger.TEN);
|
||||||
|
|
||||||
|
Message findNode = FindNodeMessage.create(id, key);
|
||||||
|
logger.info("{}", findNode);
|
||||||
|
|
||||||
|
byte[] wire = findNode.getPacket();
|
||||||
|
FindNodeMessage findNode2 = (FindNodeMessage) Message.decode(wire);
|
||||||
|
logger.info("{}", findNode2);
|
||||||
|
|
||||||
|
assertEquals(findNode.toString(), findNode2.toString());
|
||||||
|
|
||||||
|
String key2 = findNode2.getKey().toString();
|
||||||
|
assertEquals(key.toString(), key2.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test(expected = Error.class)// failure on MDC
|
||||||
|
public void test5() {
|
||||||
|
|
||||||
|
byte[] id = sha3("+++".getBytes(Charset.forName("UTF-8")));
|
||||||
|
ECKey key = ECKey.fromPrivate(BigInteger.TEN);
|
||||||
|
|
||||||
|
Message findNode = FindNodeMessage.create(id, key);
|
||||||
|
logger.info("{}", findNode);
|
||||||
|
|
||||||
|
byte[] wire = findNode.getPacket();
|
||||||
|
wire[64] = 0;
|
||||||
|
|
||||||
|
FindNodeMessage findNode2 = (FindNodeMessage) Message.decode(wire);
|
||||||
|
logger.info("{}", findNode2);
|
||||||
|
|
||||||
|
assertEquals(findNode.toString(), findNode2.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test6() {
|
||||||
|
|
||||||
|
byte[] id_1 = sha3("+++".getBytes(Charset.forName("UTF-8")));
|
||||||
|
String host_1 = "85.65.19.231";
|
||||||
|
int port_1 = 30303;
|
||||||
|
|
||||||
|
Node node_1 = new Node(id_1, host_1 , port_1);
|
||||||
|
Node node_2 = new Node(node_1.getRLP());
|
||||||
|
|
||||||
|
byte[] id_2 = node_2.getId();
|
||||||
|
String host_2 = node_2.getHost();
|
||||||
|
int port_2 = node_2.getPort();
|
||||||
|
|
||||||
|
assertEquals(Hex.toHexString(id_1), Hex.toHexString(id_2));
|
||||||
|
assertEquals(host_1, host_2);
|
||||||
|
assertTrue(port_1 == port_2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Test // Neighbors parse data
|
||||||
|
public void test7() {
|
||||||
|
|
||||||
|
byte[] wire =
|
||||||
|
Hex.decode("d5106e888eeca1e0b4a93bf17c325f912b43ca4176a000966619aa6a96ac9d5a60e66c73ed5629c13d4d0c806a3127379541e8d90d7fcb52c33c5e36557ad92dfed9619fcd3b92e42683aed89bd3c6eef6b59bd0237c36d83ebb0075a59903f50104f90200f901f8f8528c38352e36352e31392e32333182f310b840aeb2dd107edd996adf1bbf835fb3f9a11aabb7ed3dfef84c7a3c8767482bff522906a11e8cddee969153bf5944e64e37943db509bb4cc714c217f20483802ec0f8528c38352e36352e31392e32333182e5b4b840b70cdf8f23024a65afbf12110ca06fa5c37bd9fe4f6234a0120cdaaf16e8bb96d090d0164c316aaa18158d346e9b0a29ad9bfa0404ab4ee9906adfbacb01c21bf8528c38352e36352e31392e32333182df38b840ed8e01b5f5468f32de23a7524af1b35605ffd7cdb79af4eacd522c94f8ed849bb81dfed4992c179caeef0952ecad2d868503164a434c300356b369a33c159289f8528c38352e36352e31392e32333182df38b840136996f11c2c80f231987fc4f0cbd061cb021c63afaf5dd879e7c851a57be8d023af14bc201be81588ecab7971693b3f689a4854df74ad2e2334e88ae76aa122f8528c38352e36352e31392e32333182f303b840742eac32e1e2343b89c03a20fc051854ea6a3ff28ca918d1994fe1e32d6d77ab63352131db3ed0e7d6cc057d859c114b102f49052daee3d1c5f5fdaab972e655f8528c38352e36352e31392e32333182f310b8407d9e1f9ceb66fc21787b830554d604f933be203be9366710fb33355975e874a72b87837cf28b1b9ae171826b64e3c5d178326cbf71f89b3dec614816a1a40ce38454f6b578");
|
||||||
|
|
||||||
|
NeighborsMessage msg1 = (NeighborsMessage) NeighborsMessage.decode(wire);
|
||||||
|
|
||||||
|
ECKey key = ECKey.fromPrivate(BigInteger.TEN);
|
||||||
|
NeighborsMessage msg2 = (NeighborsMessage) NeighborsMessage.create(msg1.getNodes(), key);
|
||||||
|
|
||||||
|
NeighborsMessage msg3 = (NeighborsMessage) NeighborsMessage.decode(msg2.getPacket());
|
||||||
|
|
||||||
|
for (int i = 0; i < msg1.getNodes().size(); ++i) {
|
||||||
|
|
||||||
|
Node node_1 = msg1.getNodes().get(i);
|
||||||
|
Node node_3 = msg3.getNodes().get(i);
|
||||||
|
|
||||||
|
assertEquals(node_1.toString(), node_3.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println(msg1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test // FindNodeMessage parse data
|
||||||
|
public void test8() {
|
||||||
|
|
||||||
|
byte[] wire =
|
||||||
|
Hex.decode("3770d98825a42cb69edf70ffdf8d6d2b28a8c5499a7e3350e4a42c94652339cac3f8e9c3b5a181c8dd13e491ad9229f6a8bd018d786e1fb9e5264f43bbd6ce93af9bc85b468dee651bcd518561f83cb166da7aef7e506057dc2fbb2ea582bcc00003f847b84083fba54f6bb80ce31f6d5d1ec0a9a2e4685bc185115b01da6dcb70cd13116a6bd08b86ffe60b7d7ea56c6498848e3741113f8e70b9f0d12dbfe895680d03fd658454f6e772");
|
||||||
|
|
||||||
|
FindNodeMessage msg1 = (FindNodeMessage) FindNodeMessage.decode(wire);
|
||||||
|
|
||||||
|
ECKey key = ECKey.fromPrivate(BigInteger.TEN);
|
||||||
|
FindNodeMessage msg2 = FindNodeMessage.create(msg1.getTarget(), key);
|
||||||
|
|
||||||
|
FindNodeMessage msg3 = (FindNodeMessage) FindNodeMessage.decode(msg2.getPacket());
|
||||||
|
|
||||||
|
Assert.assertEquals(Hex.toHexString(msg1.getTarget()), Hex.toHexString(msg3.getTarget()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Ignore //TODO #POC9
|
||||||
|
@Test // Ping parse data
|
||||||
|
public void test9() {
|
||||||
|
// wire: 4c62e1b75f4003ef77032006a142bbf31772936a1e5098566b28a04a5c71c73f1f2c9f539a85458c50a554de12da9d7e69fb2507f7c0788885508d385bbe7a9538fa675712aa1eaad29902bb46eee4531d00a10fd81179e4151929f60fec4dc50001ce87302e302e302e30808454f8483c
|
||||||
|
// PingMessage: {mdc=4c62e1b75f4003ef77032006a142bbf31772936a1e5098566b28a04a5c71c73f, signature=1f2c9f539a85458c50a554de12da9d7e69fb2507f7c0788885508d385bbe7a9538fa675712aa1eaad29902bb46eee4531d00a10fd81179e4151929f60fec4dc500, type=01, data=ce87302e302e302e30808454f8483c}
|
||||||
|
|
||||||
|
byte[] wire =
|
||||||
|
Hex.decode("4c62e1b75f4003ef77032006a142bbf31772936a1e5098566b28a04a5c71c73f1f2c9f539a85458c50a554de12da9d7e69fb2507f7c0788885508d385bbe7a9538fa675712aa1eaad29902bb46eee4531d00a10fd81179e4151929f60fec4dc50001ce87302e302e302e30808454f8483c");
|
||||||
|
|
||||||
|
PingMessage msg1 = (PingMessage)Message.decode(wire);
|
||||||
|
|
||||||
|
ECKey key = ECKey.fromPrivate(BigInteger.TEN);
|
||||||
|
PingMessage msg2 = PingMessage.create(msg1.getHost(), msg1.getPort(), key);
|
||||||
|
PingMessage msg3 = (PingMessage)Message.decode(msg2.getPacket());
|
||||||
|
|
||||||
|
assertEquals(msg1.getHost(), msg3.getHost());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test // Pong parse data
|
||||||
|
public void test10(){
|
||||||
|
// wire: 84db9bf6a1f7a3444f4d4946155da16c63a51abdd6822ac683d8243f260b99b265601b769acebfe3c76ddeb6e83e924f2bac2beca0c802ff0745d349bd58bc6662d62d38c2a3bb3e167a333d7d099496ebd35e096c5c1ee1587e9bd11f20e3d80002e6a079d49bdba3a7acfc9a2881d768d1aa246c2486ab166f0305a863bd47c5d21e0e8454f8483c
|
||||||
|
// PongMessage: {mdc=84db9bf6a1f7a3444f4d4946155da16c63a51abdd6822ac683d8243f260b99b2, signature=65601b769acebfe3c76ddeb6e83e924f2bac2beca0c802ff0745d349bd58bc6662d62d38c2a3bb3e167a333d7d099496ebd35e096c5c1ee1587e9bd11f20e3d800, type=02, data=e6a079d49bdba3a7acfc9a2881d768d1aa246c2486ab166f0305a863bd47c5d21e0e8454f8483c}
|
||||||
|
|
||||||
|
byte[] wire =
|
||||||
|
Hex.decode("84db9bf6a1f7a3444f4d4946155da16c63a51abdd6822ac683d8243f260b99b265601b769acebfe3c76ddeb6e83e924f2bac2beca0c802ff0745d349bd58bc6662d62d38c2a3bb3e167a333d7d099496ebd35e096c5c1ee1587e9bd11f20e3d80002e6a079d49bdba3a7acfc9a2881d768d1aa246c2486ab166f0305a863bd47c5d21e0e8454f8483c");
|
||||||
|
|
||||||
|
PongMessage msg1 = (PongMessage)Message.decode(wire);
|
||||||
|
|
||||||
|
ECKey key = ECKey.fromPrivate(BigInteger.TEN);
|
||||||
|
PongMessage msg2 = PongMessage.create(msg1.getToken(), key);
|
||||||
|
|
||||||
|
PongMessage msg3 = (PongMessage)Message.decode(msg2.getPacket());
|
||||||
|
assertEquals( Hex.toHexString(msg1.getToken()), Hex.toHexString(msg3.getToken()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
package org.ethereum.net.rlpx;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import org.ethereum.crypto.ECKey;
|
||||||
|
import org.ethereum.net.client.Capability;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by devrandom on 2015-04-11.
|
||||||
|
*/
|
||||||
|
public class RlpxConnectionTest {
|
||||||
|
private FrameCodec iCodec;
|
||||||
|
private FrameCodec rCodec;
|
||||||
|
private EncryptionHandshake initiator;
|
||||||
|
private EncryptionHandshake responder;
|
||||||
|
private HandshakeMessage iMessage;
|
||||||
|
private PipedInputStream to;
|
||||||
|
private PipedOutputStream toOut;
|
||||||
|
private PipedInputStream from;
|
||||||
|
private PipedOutputStream fromOut;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws IOException {
|
||||||
|
ECKey remoteKey = new ECKey().decompress();
|
||||||
|
ECKey myKey = new ECKey().decompress();
|
||||||
|
initiator = new EncryptionHandshake(remoteKey.getPubKeyPoint());
|
||||||
|
responder = new EncryptionHandshake();
|
||||||
|
AuthInitiateMessage initiate = initiator.createAuthInitiate(null, myKey);
|
||||||
|
byte[] initiatePacket = initiator.encryptAuthMessage(initiate);
|
||||||
|
byte[] responsePacket = responder.handleAuthInitiate(initiatePacket, remoteKey);
|
||||||
|
initiator.handleAuthResponse(myKey, initiatePacket, responsePacket);
|
||||||
|
to = new PipedInputStream(1024*1024);
|
||||||
|
toOut = new PipedOutputStream(to);
|
||||||
|
from = new PipedInputStream(1024*1024);
|
||||||
|
fromOut = new PipedOutputStream(from);
|
||||||
|
iCodec = new FrameCodec(initiator.getSecrets());
|
||||||
|
rCodec = new FrameCodec(responder.getSecrets());
|
||||||
|
byte[] nodeId = {1, 2, 3, 4};
|
||||||
|
iMessage = new HandshakeMessage(
|
||||||
|
123,
|
||||||
|
"abcd",
|
||||||
|
Lists.newArrayList(
|
||||||
|
new Capability("zz", (byte) 1),
|
||||||
|
new Capability("yy", (byte) 3)
|
||||||
|
),
|
||||||
|
3333,
|
||||||
|
nodeId
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFrame() throws Exception {
|
||||||
|
byte[] payload = new byte[123];
|
||||||
|
new SecureRandom().nextBytes(payload);
|
||||||
|
FrameCodec.Frame frame = new FrameCodec.Frame(12345, 123, new ByteArrayInputStream(payload));
|
||||||
|
iCodec.writeFrame(frame, toOut);
|
||||||
|
FrameCodec.Frame frame1 = rCodec.readFrame(new DataInputStream(to));
|
||||||
|
byte[] payload1 = new byte[frame1.size];
|
||||||
|
assertEquals(frame.size, frame1.size);
|
||||||
|
frame1.payload.read(payload1);
|
||||||
|
assertArrayEquals(payload, payload1);
|
||||||
|
assertEquals(frame.type, frame1.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMessageEncoding() throws IOException {
|
||||||
|
byte[] wire = iMessage.encode();
|
||||||
|
HandshakeMessage message1 = HandshakeMessage.parse(wire);
|
||||||
|
assertEquals(123, message1.version);
|
||||||
|
assertEquals("abcd", message1.name);
|
||||||
|
assertEquals(3333, message1.listenPort);
|
||||||
|
assertArrayEquals(message1.nodeId, message1.nodeId);
|
||||||
|
assertEquals(iMessage.caps, message1.caps);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHandshake() throws IOException {
|
||||||
|
RlpxConnection iConn = new RlpxConnection(initiator.getSecrets(), from, toOut);
|
||||||
|
RlpxConnection rConn = new RlpxConnection(responder.getSecrets(), to, fromOut);
|
||||||
|
iConn.sendProtocolHandshake(iMessage);
|
||||||
|
rConn.handleNextMessage();
|
||||||
|
HandshakeMessage receivedMessage = rConn.getHandshakeMessage();
|
||||||
|
assertNotNull(receivedMessage);
|
||||||
|
assertArrayEquals(iMessage.nodeId, receivedMessage.nodeId);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,150 @@
|
||||||
|
package org.ethereum.net.wire;
|
||||||
|
|
||||||
|
import org.ethereum.net.client.Capability;
|
||||||
|
import org.ethereum.net.eth.EthHandler;
|
||||||
|
import org.ethereum.net.eth.EthMessageCodes;
|
||||||
|
import org.ethereum.net.p2p.P2pHandler;
|
||||||
|
import org.ethereum.net.p2p.P2pMessageCodes;
|
||||||
|
import org.ethereum.net.shh.ShhHandler;
|
||||||
|
import org.ethereum.net.shh.ShhMessageCodes;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Roman Mandeleil
|
||||||
|
* @since 15.10.2014
|
||||||
|
*/
|
||||||
|
public class AdaptiveMessageIdsTest {
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
EthMessageCodes.setOffset((byte) 0x00);
|
||||||
|
ShhMessageCodes.setOffset((byte) 0x00);
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
EthMessageCodes.setOffset((byte) 0x00);
|
||||||
|
ShhMessageCodes.setOffset((byte) 0x00);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test1() {
|
||||||
|
|
||||||
|
Assert.assertEquals(7, P2pMessageCodes.values().length);
|
||||||
|
|
||||||
|
Assert.assertEquals(0, P2pMessageCodes.HELLO.asByte());
|
||||||
|
Assert.assertEquals(1, P2pMessageCodes.DISCONNECT.asByte());
|
||||||
|
Assert.assertEquals(2, P2pMessageCodes.PING.asByte());
|
||||||
|
Assert.assertEquals(3, P2pMessageCodes.PONG.asByte());
|
||||||
|
Assert.assertEquals(4, P2pMessageCodes.GET_PEERS.asByte());
|
||||||
|
Assert.assertEquals(5, P2pMessageCodes.PEERS.asByte());
|
||||||
|
Assert.assertEquals(15, P2pMessageCodes.USER.asByte());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test2() {
|
||||||
|
|
||||||
|
Assert.assertEquals(9, EthMessageCodes.values().length);
|
||||||
|
|
||||||
|
Assert.assertEquals(0, EthMessageCodes.STATUS.asByte());
|
||||||
|
Assert.assertEquals(1, EthMessageCodes.GET_TRANSACTIONS.asByte());
|
||||||
|
Assert.assertEquals(2, EthMessageCodes.TRANSACTIONS.asByte());
|
||||||
|
Assert.assertEquals(3, EthMessageCodes.GET_BLOCK_HASHES.asByte());
|
||||||
|
Assert.assertEquals(4, EthMessageCodes.BLOCK_HASHES.asByte());
|
||||||
|
Assert.assertEquals(5, EthMessageCodes.GET_BLOCKS.asByte());
|
||||||
|
Assert.assertEquals(6, EthMessageCodes.BLOCKS.asByte());
|
||||||
|
Assert.assertEquals(7, EthMessageCodes.NEW_BLOCK.asByte());
|
||||||
|
Assert.assertEquals(8, EthMessageCodes.PACKET_COUNT.asByte());
|
||||||
|
|
||||||
|
EthMessageCodes.setOffset((byte) 0x10);
|
||||||
|
Assert.assertEquals(0x10 + 0, EthMessageCodes.STATUS.asByte());
|
||||||
|
Assert.assertEquals(0x10 + 1, EthMessageCodes.GET_TRANSACTIONS.asByte());
|
||||||
|
Assert.assertEquals(0x10 + 2, EthMessageCodes.TRANSACTIONS.asByte());
|
||||||
|
Assert.assertEquals(0x10 + 3, EthMessageCodes.GET_BLOCK_HASHES.asByte());
|
||||||
|
Assert.assertEquals(0x10 + 4, EthMessageCodes.BLOCK_HASHES.asByte());
|
||||||
|
Assert.assertEquals(0x10 + 5, EthMessageCodes.GET_BLOCKS.asByte());
|
||||||
|
Assert.assertEquals(0x10 + 6, EthMessageCodes.BLOCKS.asByte());
|
||||||
|
Assert.assertEquals(0x10 + 7, EthMessageCodes.NEW_BLOCK.asByte());
|
||||||
|
Assert.assertEquals(0x10 + 8, EthMessageCodes.PACKET_COUNT.asByte());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test3() {
|
||||||
|
|
||||||
|
Assert.assertEquals(5, ShhMessageCodes.values().length);
|
||||||
|
|
||||||
|
Assert.assertEquals(0, ShhMessageCodes.STATUS.asByte());
|
||||||
|
Assert.assertEquals(1, ShhMessageCodes.MESSAGE.asByte());
|
||||||
|
Assert.assertEquals(2, ShhMessageCodes.ADD_FILTER.asByte());
|
||||||
|
Assert.assertEquals(3, ShhMessageCodes.REMOVE_FILTER.asByte());
|
||||||
|
Assert.assertEquals(4, ShhMessageCodes.PACKET_COUNT.asByte());
|
||||||
|
|
||||||
|
ShhMessageCodes.setOffset((byte) 0x20);
|
||||||
|
Assert.assertEquals(0x20 + 0, ShhMessageCodes.STATUS.asByte());
|
||||||
|
Assert.assertEquals(0x20 + 1, ShhMessageCodes.MESSAGE.asByte());
|
||||||
|
Assert.assertEquals(0x20 + 2, ShhMessageCodes.ADD_FILTER.asByte());
|
||||||
|
Assert.assertEquals(0x20 + 3, ShhMessageCodes.REMOVE_FILTER.asByte());
|
||||||
|
Assert.assertEquals(0x20 + 4, ShhMessageCodes.PACKET_COUNT.asByte());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test4() {
|
||||||
|
|
||||||
|
P2pHandler p2pHandler = new P2pHandler();
|
||||||
|
|
||||||
|
List<Capability> capabilities = Arrays.asList(
|
||||||
|
new Capability(Capability.ETH, EthHandler.VERSION),
|
||||||
|
new Capability(Capability.SHH, ShhHandler.VERSION));
|
||||||
|
p2pHandler.adaptMessageIds(capabilities);
|
||||||
|
|
||||||
|
Assert.assertEquals(0x10 + 0, EthMessageCodes.STATUS.asByte());
|
||||||
|
Assert.assertEquals(0x10 + 1, EthMessageCodes.GET_TRANSACTIONS.asByte());
|
||||||
|
Assert.assertEquals(0x10 + 2, EthMessageCodes.TRANSACTIONS.asByte());
|
||||||
|
Assert.assertEquals(0x10 + 3, EthMessageCodes.GET_BLOCK_HASHES.asByte());
|
||||||
|
Assert.assertEquals(0x10 + 4, EthMessageCodes.BLOCK_HASHES.asByte());
|
||||||
|
Assert.assertEquals(0x10 + 5, EthMessageCodes.GET_BLOCKS.asByte());
|
||||||
|
Assert.assertEquals(0x10 + 6, EthMessageCodes.BLOCKS.asByte());
|
||||||
|
Assert.assertEquals(0x10 + 7, EthMessageCodes.NEW_BLOCK.asByte());
|
||||||
|
Assert.assertEquals(0x10 + 8, EthMessageCodes.PACKET_COUNT.asByte());
|
||||||
|
|
||||||
|
Assert.assertEquals(0x19 + 0, ShhMessageCodes.STATUS.asByte());
|
||||||
|
Assert.assertEquals(0x19 + 1, ShhMessageCodes.MESSAGE.asByte());
|
||||||
|
Assert.assertEquals(0x19 + 2, ShhMessageCodes.ADD_FILTER.asByte());
|
||||||
|
Assert.assertEquals(0x19 + 3, ShhMessageCodes.REMOVE_FILTER.asByte());
|
||||||
|
Assert.assertEquals(0x19 + 4, ShhMessageCodes.PACKET_COUNT.asByte());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // Capabilities should be read in alphabetical order
|
||||||
|
public void test5() {
|
||||||
|
|
||||||
|
P2pHandler p2pHandler = new P2pHandler();
|
||||||
|
|
||||||
|
List<Capability> capabilities = Arrays.asList(
|
||||||
|
new Capability(Capability.SHH, ShhHandler.VERSION),
|
||||||
|
new Capability(Capability.ETH, EthHandler.VERSION));
|
||||||
|
p2pHandler.adaptMessageIds(capabilities);
|
||||||
|
|
||||||
|
Assert.assertEquals(0x10 + 0, EthMessageCodes.STATUS.asByte());
|
||||||
|
Assert.assertEquals(0x10 + 1, EthMessageCodes.GET_TRANSACTIONS.asByte());
|
||||||
|
Assert.assertEquals(0x10 + 2, EthMessageCodes.TRANSACTIONS.asByte());
|
||||||
|
Assert.assertEquals(0x10 + 3, EthMessageCodes.GET_BLOCK_HASHES.asByte());
|
||||||
|
Assert.assertEquals(0x10 + 4, EthMessageCodes.BLOCK_HASHES.asByte());
|
||||||
|
Assert.assertEquals(0x10 + 5, EthMessageCodes.GET_BLOCKS.asByte());
|
||||||
|
Assert.assertEquals(0x10 + 6, EthMessageCodes.BLOCKS.asByte());
|
||||||
|
Assert.assertEquals(0x10 + 7, EthMessageCodes.NEW_BLOCK.asByte());
|
||||||
|
Assert.assertEquals(0x10 + 8, EthMessageCodes.PACKET_COUNT.asByte());
|
||||||
|
|
||||||
|
Assert.assertEquals(0x19 + 0, ShhMessageCodes.STATUS.asByte());
|
||||||
|
Assert.assertEquals(0x19 + 1, ShhMessageCodes.MESSAGE.asByte());
|
||||||
|
Assert.assertEquals(0x19 + 2, ShhMessageCodes.ADD_FILTER.asByte());
|
||||||
|
Assert.assertEquals(0x19 + 3, ShhMessageCodes.REMOVE_FILTER.asByte());
|
||||||
|
Assert.assertEquals(0x19 + 4, ShhMessageCodes.PACKET_COUNT.asByte());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
package org.ethereum.serpent;
|
||||||
|
|
||||||
|
import org.ethereum.serpent.SerpentCompiler;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Roman Mandeleil
|
||||||
|
* @since 28.05.2014
|
||||||
|
*/
|
||||||
|
public class MachineCompileTest {
|
||||||
|
|
||||||
|
@Test // very simple contract
|
||||||
|
public void test1() {
|
||||||
|
|
||||||
|
String code = "a=2";
|
||||||
|
String expected = "6005600c60003960056000f36002600052";
|
||||||
|
String asm = SerpentCompiler.compile(code);
|
||||||
|
byte[] machineCode = SerpentCompiler.compileAssemblyToMachine(asm);
|
||||||
|
byte[] vmReadyCode = SerpentCompiler.encodeMachineCodeForVMRun(machineCode, null);
|
||||||
|
|
||||||
|
String result = Hex.toHexString(vmReadyCode);
|
||||||
|
assertEquals(expected, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // contract for 256 bytes (len 2 bytes)
|
||||||
|
public void test2() {
|
||||||
|
|
||||||
|
String code = "a=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\na=2\n[asm PUSH10 asm]";
|
||||||
|
String expected = "610100600e6000396101006000f360026000526002600052600260005260026000526002600052600260005260026000526002600052600260005260026000526002600052600260005260026000526002600052600260005260026000526002600052600260005260026000526002600052600260005260026000526002600052600260005260026000526002600052600260005260026000526002600052600260005260026000526002600052600260005260026000526002600052600260005260026000526002600052600260005260026000526002600052600260005260026000526002600052600260005260026000526002600052600260005260026000526002600052600260005269";
|
||||||
|
String asm = SerpentCompiler.compile(code);
|
||||||
|
byte[] machineCode = SerpentCompiler.compileAssemblyToMachine(asm);
|
||||||
|
byte[] vmReadyCode = SerpentCompiler.encodeMachineCodeForVMRun(machineCode, null);
|
||||||
|
|
||||||
|
String result = Hex.toHexString(vmReadyCode);
|
||||||
|
|
||||||
|
assertEquals(expected, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // contract for if jump
|
||||||
|
public void test3() {
|
||||||
|
|
||||||
|
String code = "a=2\n" +
|
||||||
|
"if a>0:\n" +
|
||||||
|
" b = 3\n" +
|
||||||
|
"else: \n" +
|
||||||
|
" c = 4";
|
||||||
|
// String expected = "610100600e6000396101006000f260026000546002600054600260005460026000546002600054600260005460026000546002600054600260005460026000546002600054600260005460026000546002600054600260005460026000546002600054600260005460026000546002600054600260005460026000546002600054600260005460026000546002600054600260005460026000546002600054600260005460026000546002600054600260005460026000546002600054600260005460026000546002600054600260005460026000546002600054600260005460026000546002600054600260005460026000546002600054600260005460026000546002600054600260005469";
|
||||||
|
String asm = SerpentCompiler.compile(code);
|
||||||
|
byte[] machineCode = SerpentCompiler.compileAssemblyToMachine(asm);
|
||||||
|
byte[] vmReadyCode = SerpentCompiler.encodeMachineCodeForVMRun(machineCode, null);
|
||||||
|
|
||||||
|
System.out.println(asm);
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,328 @@
|
||||||
|
package org.ethereum.util;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.spongycastle.util.BigIntegers;
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
public class ByteUtilTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAppendByte() {
|
||||||
|
byte[] bytes = "tes".getBytes();
|
||||||
|
byte b = 0x74;
|
||||||
|
Assert.assertArrayEquals("test".getBytes(), ByteUtil.appendByte(bytes, b));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBigIntegerToBytes() {
|
||||||
|
byte[] expecteds = new byte[]{(byte) 0xff, (byte) 0xec, 0x78};
|
||||||
|
BigInteger b = BigInteger.valueOf(16772216);
|
||||||
|
byte[] actuals = ByteUtil.bigIntegerToBytes(b);
|
||||||
|
assertArrayEquals(expecteds, actuals);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBigIntegerToBytesNegative() {
|
||||||
|
byte[] expecteds = new byte[]{(byte) 0xff, 0x0, 0x13, (byte) 0x88};
|
||||||
|
BigInteger b = BigInteger.valueOf(-16772216);
|
||||||
|
byte[] actuals = ByteUtil.bigIntegerToBytes(b);
|
||||||
|
assertArrayEquals(expecteds, actuals);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBigIntegerToBytesZero() {
|
||||||
|
byte[] expecteds = new byte[]{0x00};
|
||||||
|
BigInteger b = BigInteger.ZERO;
|
||||||
|
byte[] actuals = ByteUtil.bigIntegerToBytes(b);
|
||||||
|
assertArrayEquals(expecteds, actuals);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testToHexString() {
|
||||||
|
assertEquals("", ByteUtil.toHexString(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCalcPacketLength() {
|
||||||
|
byte[] test = new byte[]{0x0f, 0x10, 0x43};
|
||||||
|
byte[] expected = new byte[]{0x00, 0x00, 0x00, 0x03};
|
||||||
|
assertArrayEquals(expected, ByteUtil.calcPacketLength(test));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testByteArrayToInt() {
|
||||||
|
assertEquals(0, ByteUtil.byteArrayToInt(null));
|
||||||
|
assertEquals(0, ByteUtil.byteArrayToInt(new byte[0]));
|
||||||
|
|
||||||
|
// byte[] x = new byte[] { 5,1,7,0,8 };
|
||||||
|
// long start = System.currentTimeMillis();
|
||||||
|
// for (int i = 0; i < 100000000; i++) {
|
||||||
|
// ByteArray.read32bit(x, 0);
|
||||||
|
// }
|
||||||
|
// long end = System.currentTimeMillis();
|
||||||
|
// System.out.println(end - start + "ms");
|
||||||
|
//
|
||||||
|
// long start1 = System.currentTimeMillis();
|
||||||
|
// for (int i = 0; i < 100000000; i++) {
|
||||||
|
// new BigInteger(1, x).intValue();
|
||||||
|
// }
|
||||||
|
// long end1 = System.currentTimeMillis();
|
||||||
|
// System.out.println(end1 - start1 + "ms");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNumBytes() {
|
||||||
|
String test1 = "0";
|
||||||
|
String test2 = "1";
|
||||||
|
String test3 = "1000000000"; //3B9ACA00
|
||||||
|
int expected1 = 1;
|
||||||
|
int expected2 = 1;
|
||||||
|
int expected3 = 4;
|
||||||
|
assertEquals(expected1, ByteUtil.numBytes(test1));
|
||||||
|
assertEquals(expected2, ByteUtil.numBytes(test2));
|
||||||
|
assertEquals(expected3, ByteUtil.numBytes(test3));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStripLeadingZeroes() {
|
||||||
|
byte[] test1 = null;
|
||||||
|
byte[] test2 = new byte[]{};
|
||||||
|
byte[] test3 = new byte[]{0x00};
|
||||||
|
byte[] test4 = new byte[]{0x00, 0x01};
|
||||||
|
byte[] test5 = new byte[]{0x00, 0x00, 0x01};
|
||||||
|
byte[] expected1 = null;
|
||||||
|
byte[] expected2 = new byte[]{0};
|
||||||
|
byte[] expected3 = new byte[]{0};
|
||||||
|
byte[] expected4 = new byte[]{0x01};
|
||||||
|
byte[] expected5 = new byte[]{0x01};
|
||||||
|
assertArrayEquals(expected1, ByteUtil.stripLeadingZeroes(test1));
|
||||||
|
assertArrayEquals(expected2, ByteUtil.stripLeadingZeroes(test2));
|
||||||
|
assertArrayEquals(expected3, ByteUtil.stripLeadingZeroes(test3));
|
||||||
|
assertArrayEquals(expected4, ByteUtil.stripLeadingZeroes(test4));
|
||||||
|
assertArrayEquals(expected5, ByteUtil.stripLeadingZeroes(test5));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMatchingNibbleLength1() {
|
||||||
|
// a larger than b
|
||||||
|
byte[] a = new byte[]{0x00, 0x01};
|
||||||
|
byte[] b = new byte[]{0x00};
|
||||||
|
int result = ByteUtil.matchingNibbleLength(a, b);
|
||||||
|
assertEquals(1, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMatchingNibbleLength2() {
|
||||||
|
// b larger than a
|
||||||
|
byte[] a = new byte[]{0x00};
|
||||||
|
byte[] b = new byte[]{0x00, 0x01};
|
||||||
|
int result = ByteUtil.matchingNibbleLength(a, b);
|
||||||
|
assertEquals(1, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMatchingNibbleLength3() {
|
||||||
|
// a and b the same length equal
|
||||||
|
byte[] a = new byte[]{0x00};
|
||||||
|
byte[] b = new byte[]{0x00};
|
||||||
|
int result = ByteUtil.matchingNibbleLength(a, b);
|
||||||
|
assertEquals(1, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMatchingNibbleLength4() {
|
||||||
|
// a and b the same length not equal
|
||||||
|
byte[] a = new byte[]{0x01};
|
||||||
|
byte[] b = new byte[]{0x00};
|
||||||
|
int result = ByteUtil.matchingNibbleLength(a, b);
|
||||||
|
assertEquals(0, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNiceNiblesOutput_1() {
|
||||||
|
byte[] test = {7, 0, 7, 5, 7, 0, 7, 0, 7, 9};
|
||||||
|
String result = "\\x07\\x00\\x07\\x05\\x07\\x00\\x07\\x00\\x07\\x09";
|
||||||
|
assertEquals(result, ByteUtil.nibblesToPrettyString(test));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNiceNiblesOutput_2() {
|
||||||
|
byte[] test = {7, 0, 7, 0xf, 7, 0, 0xa, 0, 7, 9};
|
||||||
|
String result = "\\x07\\x00\\x07\\x0f\\x07\\x00\\x0a\\x00\\x07\\x09";
|
||||||
|
assertEquals(result, ByteUtil.nibblesToPrettyString(test));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = NullPointerException.class)
|
||||||
|
public void testMatchingNibbleLength5() {
|
||||||
|
// a == null
|
||||||
|
byte[] a = null;
|
||||||
|
byte[] b = new byte[]{0x00};
|
||||||
|
ByteUtil.matchingNibbleLength(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = NullPointerException.class)
|
||||||
|
public void testMatchingNibbleLength6() {
|
||||||
|
// b == null
|
||||||
|
byte[] a = new byte[]{0x00};
|
||||||
|
byte[] b = null;
|
||||||
|
ByteUtil.matchingNibbleLength(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMatchingNibbleLength7() {
|
||||||
|
// a or b is empty
|
||||||
|
byte[] a = new byte[0];
|
||||||
|
byte[] b = new byte[]{0x00};
|
||||||
|
int result = ByteUtil.matchingNibbleLength(a, b);
|
||||||
|
assertEquals(0, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This test shows the difference between iterating over,
|
||||||
|
* and comparing byte[] vs BigInteger value.
|
||||||
|
*
|
||||||
|
* Results indicate that the former has ~15x better performance.
|
||||||
|
* Therefore this is used in the Miner.mine() method.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testIncrementPerformance() {
|
||||||
|
boolean testEnabled = false;
|
||||||
|
|
||||||
|
if (testEnabled) {
|
||||||
|
byte[] counter1 = new byte[4];
|
||||||
|
byte[] max = ByteBuffer.allocate(4).putInt(Integer.MAX_VALUE).array();
|
||||||
|
long start1 = System.currentTimeMillis();
|
||||||
|
while (ByteUtil.increment(counter1)) {
|
||||||
|
if (FastByteComparisons.compareTo(counter1, 0, 4, max, 0, 4) == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println(System.currentTimeMillis() - start1 + "ms to reach: " + Hex.toHexString(counter1));
|
||||||
|
|
||||||
|
BigInteger counter2 = BigInteger.ZERO;
|
||||||
|
long start2 = System.currentTimeMillis();
|
||||||
|
while (true) {
|
||||||
|
if (counter2.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
counter2 = counter2.add(BigInteger.ONE);
|
||||||
|
}
|
||||||
|
System.out.println(System.currentTimeMillis() - start2 + "ms to reach: " + Hex.toHexString(BigIntegers.asUnsignedByteArray(4, counter2)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void firstNonZeroByte_1() {
|
||||||
|
|
||||||
|
byte[] data = Hex.decode("0000000000000000000000000000000000000000000000000000000000000000");
|
||||||
|
int result = ByteUtil.firstNonZeroByte(data);
|
||||||
|
|
||||||
|
assertEquals(-1, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void firstNonZeroByte_2() {
|
||||||
|
|
||||||
|
byte[] data = Hex.decode("0000000000000000000000000000000000000000000000000000000000332211");
|
||||||
|
int result = ByteUtil.firstNonZeroByte(data);
|
||||||
|
|
||||||
|
assertEquals(29, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void firstNonZeroByte_3() {
|
||||||
|
|
||||||
|
byte[] data = Hex.decode("2211009988776655443322110099887766554433221100998877665544332211");
|
||||||
|
int result = ByteUtil.firstNonZeroByte(data);
|
||||||
|
|
||||||
|
assertEquals(0, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setBitTest() {
|
||||||
|
/*
|
||||||
|
Set on
|
||||||
|
*/
|
||||||
|
byte[] data = ByteBuffer.allocate(4).putInt(0).array();
|
||||||
|
int posBit = 24;
|
||||||
|
int expected = 16777216;
|
||||||
|
int result = -1;
|
||||||
|
byte[] ret = ByteUtil.setBit(data, posBit, 1);
|
||||||
|
result = ByteUtil.byteArrayToInt(ret);
|
||||||
|
assertTrue(expected == result);
|
||||||
|
|
||||||
|
posBit = 25;
|
||||||
|
expected = 50331648;
|
||||||
|
ret = ByteUtil.setBit(data, posBit, 1);
|
||||||
|
result = ByteUtil.byteArrayToInt(ret);
|
||||||
|
assertTrue(expected == result);
|
||||||
|
|
||||||
|
posBit = 2;
|
||||||
|
expected = 50331652;
|
||||||
|
ret = ByteUtil.setBit(data, posBit, 1);
|
||||||
|
result = ByteUtil.byteArrayToInt(ret);
|
||||||
|
assertTrue(expected == result);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Set off
|
||||||
|
*/
|
||||||
|
posBit = 24;
|
||||||
|
expected = 33554436;
|
||||||
|
ret = ByteUtil.setBit(data, posBit, 0);
|
||||||
|
result = ByteUtil.byteArrayToInt(ret);
|
||||||
|
assertTrue(expected == result);
|
||||||
|
|
||||||
|
posBit = 25;
|
||||||
|
expected = 4;
|
||||||
|
ret = ByteUtil.setBit(data, posBit, 0);
|
||||||
|
result = ByteUtil.byteArrayToInt(ret);
|
||||||
|
assertTrue(expected == result);
|
||||||
|
|
||||||
|
posBit = 2;
|
||||||
|
expected = 0;
|
||||||
|
ret = ByteUtil.setBit(data, posBit, 0);
|
||||||
|
result = ByteUtil.byteArrayToInt(ret);
|
||||||
|
assertTrue(expected == result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getBitTest() {
|
||||||
|
byte[] data = ByteBuffer.allocate(4).putInt(0).array();
|
||||||
|
ByteUtil.setBit(data, 24, 1);
|
||||||
|
ByteUtil.setBit(data, 25, 1);
|
||||||
|
ByteUtil.setBit(data, 2, 1);
|
||||||
|
|
||||||
|
List<Integer> found = new ArrayList<>();
|
||||||
|
for (int i = 0; i < (data.length * 8); i++) {
|
||||||
|
int res = ByteUtil.getBit(data, i);
|
||||||
|
if (res == 1)
|
||||||
|
if (i != 24 && i != 25 && i != 2)
|
||||||
|
assertTrue(false);
|
||||||
|
else
|
||||||
|
found.add(i);
|
||||||
|
else {
|
||||||
|
if (i == 24 || i == 25 || i == 2)
|
||||||
|
assertTrue(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found.size() != 3)
|
||||||
|
assertTrue(false);
|
||||||
|
assertTrue(found.get(0) == 2);
|
||||||
|
assertTrue(found.get(1) == 24);
|
||||||
|
assertTrue(found.get(2) == 25);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
package org.ethereum.util;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
|
|
||||||
|
public class CompactEncoderTest {
|
||||||
|
|
||||||
|
private final static byte T = 16; // terminator
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCompactEncodeOddCompact() {
|
||||||
|
byte[] test = new byte[]{1, 2, 3, 4, 5};
|
||||||
|
byte[] expectedData = new byte[]{0x11, 0x23, 0x45};
|
||||||
|
assertArrayEquals("odd compact encode fail", expectedData, CompactEncoder.packNibbles(test));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCompactEncodeEvenCompact() {
|
||||||
|
byte[] test = new byte[]{0, 1, 2, 3, 4, 5};
|
||||||
|
byte[] expectedData = new byte[]{0x00, 0x01, 0x23, 0x45};
|
||||||
|
assertArrayEquals("even compact encode fail", expectedData, CompactEncoder.packNibbles(test));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCompactEncodeEvenTerminated() {
|
||||||
|
byte[] test = new byte[]{0, 15, 1, 12, 11, 8, T};
|
||||||
|
byte[] expectedData = new byte[]{0x20, 0x0f, 0x1c, (byte) 0xb8};
|
||||||
|
assertArrayEquals("even terminated compact encode fail", expectedData, CompactEncoder.packNibbles(test));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCompactEncodeOddTerminated() {
|
||||||
|
byte[] test = new byte[]{15, 1, 12, 11, 8, T};
|
||||||
|
byte[] expectedData = new byte[]{0x3f, 0x1c, (byte) 0xb8};
|
||||||
|
assertArrayEquals("odd terminated compact encode fail", expectedData, CompactEncoder.packNibbles(test));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCompactDecodeOddCompact() {
|
||||||
|
byte[] test = new byte[]{0x11, 0x23, 0x45};
|
||||||
|
byte[] expected = new byte[]{1, 2, 3, 4, 5};
|
||||||
|
assertArrayEquals("odd compact decode fail", expected, CompactEncoder.unpackToNibbles(test));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCompactDecodeEvenCompact() {
|
||||||
|
byte[] test = new byte[]{0x00, 0x01, 0x23, 0x45};
|
||||||
|
byte[] expected = new byte[]{0, 1, 2, 3, 4, 5};
|
||||||
|
assertArrayEquals("even compact decode fail", expected, CompactEncoder.unpackToNibbles(test));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCompactDecodeEvenTerminated() {
|
||||||
|
byte[] test = new byte[]{0x20, 0x0f, 0x1c, (byte) 0xb8};
|
||||||
|
byte[] expected = new byte[]{0, 15, 1, 12, 11, 8, T};
|
||||||
|
assertArrayEquals("even terminated compact decode fail", expected, CompactEncoder.unpackToNibbles(test));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCompactDecodeOddTerminated() {
|
||||||
|
byte[] test = new byte[]{0x3f, 0x1c, (byte) 0xb8};
|
||||||
|
byte[] expected = new byte[]{15, 1, 12, 11, 8, T};
|
||||||
|
assertArrayEquals("odd terminated compact decode fail", expected, CompactEncoder.unpackToNibbles(test));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCompactHexEncode_1() {
|
||||||
|
byte[] test = "stallion".getBytes();
|
||||||
|
byte[] result = new byte[]{7, 3, 7, 4, 6, 1, 6, 12, 6, 12, 6, 9, 6, 15, 6, 14, T};
|
||||||
|
assertArrayEquals(result, CompactEncoder.binToNibbles(test));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCompactHexEncode_2() {
|
||||||
|
byte[] test = "verb".getBytes();
|
||||||
|
byte[] result = new byte[]{7, 6, 6, 5, 7, 2, 6, 2, T};
|
||||||
|
assertArrayEquals(result, CompactEncoder.binToNibbles(test));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCompactHexEncode_3() {
|
||||||
|
byte[] test = "puppy".getBytes();
|
||||||
|
byte[] result = new byte[]{7, 0, 7, 5, 7, 0, 7, 0, 7, 9, T};
|
||||||
|
assertArrayEquals(result, CompactEncoder.binToNibbles(test));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
package org.ethereum.util;
|
||||||
|
|
||||||
|
import org.ethereum.crypto.HashUtil;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class HashUtilTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSha256_EmptyString() {
|
||||||
|
String expected1 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
|
||||||
|
String result1 = Hex.toHexString(HashUtil.sha256(new byte[0]));
|
||||||
|
assertEquals(expected1, result1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSha256_Test() {
|
||||||
|
String expected2 = "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08";
|
||||||
|
String result2 = Hex.toHexString(HashUtil.sha256("test".getBytes()));
|
||||||
|
assertEquals(expected2, result2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSha256_Multiple() {
|
||||||
|
String expected1 = "1b4f0e9851971998e732078544c96b36c3d01cedf7caa332359d6f1d83567014";
|
||||||
|
String result1 = Hex.toHexString(HashUtil.sha256("test1".getBytes()));
|
||||||
|
assertEquals(expected1, result1);
|
||||||
|
|
||||||
|
String expected2 = "60303ae22b998861bce3b28f33eec1be758a213c86c93c076dbe9f558c11c752";
|
||||||
|
String result2 = Hex.toHexString(HashUtil.sha256("test2".getBytes()));
|
||||||
|
assertEquals(expected2, result2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSha3_EmptyString() {
|
||||||
|
String expected1 = "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470";
|
||||||
|
String result1 = Hex.toHexString(HashUtil.sha3(new byte[0]));
|
||||||
|
assertEquals(expected1, result1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSha3_Test() {
|
||||||
|
String expected2 = "9c22ff5f21f0b81b113e63f7db6da94fedef11b2119b4088b89664fb9a3cb658";
|
||||||
|
String result2 = Hex.toHexString(HashUtil.sha3("test".getBytes()));
|
||||||
|
assertEquals(expected2, result2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSha3_Multiple() {
|
||||||
|
String expected1 = "6d255fc3390ee6b41191da315958b7d6a1e5b17904cc7683558f98acc57977b4";
|
||||||
|
String result1 = Hex.toHexString(HashUtil.sha3("test1".getBytes()));
|
||||||
|
assertEquals(expected1, result1);
|
||||||
|
|
||||||
|
String expected2 = "4da432f1ecd4c0ac028ebde3a3f78510a21d54087b161590a63080d33b702b8d";
|
||||||
|
String result2 = Hex.toHexString(HashUtil.sha3("test2".getBytes()));
|
||||||
|
assertEquals(expected2, result2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRIPEMD160_EmptyString() {
|
||||||
|
String expected1 = "9c1185a5c5e9fc54612808977ee8f548b2258d31";
|
||||||
|
String result1 = Hex.toHexString(HashUtil.ripemd160(new byte[0]));
|
||||||
|
assertEquals(expected1, result1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRIPEMD160_Test() {
|
||||||
|
String expected2 = "5e52fee47e6b070565f74372468cdc699de89107";
|
||||||
|
String result2 = Hex.toHexString(HashUtil.ripemd160("test".getBytes()));
|
||||||
|
assertEquals(expected2, result2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRIPEMD160_Multiple() {
|
||||||
|
String expected1 = "9295fac879006ff44812e43b83b515a06c2950aa";
|
||||||
|
String result1 = Hex.toHexString(HashUtil.ripemd160("test1".getBytes()));
|
||||||
|
assertEquals(expected1, result1);
|
||||||
|
|
||||||
|
String expected2 = "80b85ebf641abccdd26e327c5782353137a0a0af";
|
||||||
|
String result2 = Hex.toHexString(HashUtil.ripemd160("test2".getBytes()));
|
||||||
|
assertEquals(expected2, result2);
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,59 @@
|
||||||
|
package org.ethereum.util;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
public class RlpTestData {
|
||||||
|
|
||||||
|
/***********************************
|
||||||
|
* https://github.com/ethereum/tests/blob/master/rlptest.txt
|
||||||
|
*/
|
||||||
|
public static int test01 = 0;
|
||||||
|
public static String result01 = "80";
|
||||||
|
|
||||||
|
public static String test02 = "";
|
||||||
|
public static String result02 = "80";
|
||||||
|
|
||||||
|
public static String test03 = "d";
|
||||||
|
public static String result03 = "64";
|
||||||
|
|
||||||
|
public static String test04 = "cat";
|
||||||
|
public static String result04 = "83636174";
|
||||||
|
|
||||||
|
public static String test05 = "dog";
|
||||||
|
public static String result05 = "83646f67";
|
||||||
|
|
||||||
|
public static String[] test06 = new String[]{"cat", "dog"};
|
||||||
|
public static String result06 = "c88363617483646f67";
|
||||||
|
|
||||||
|
public static String[] test07 = new String[]{"dog", "god", "cat"};
|
||||||
|
public static String result07 = "cc83646f6783676f6483636174";
|
||||||
|
|
||||||
|
public static int test08 = 1;
|
||||||
|
public static String result08 = "01";
|
||||||
|
|
||||||
|
public static int test09 = 10;
|
||||||
|
public static String result09 = "0a";
|
||||||
|
|
||||||
|
public static int test10 = 100;
|
||||||
|
public static String result10 = "64";
|
||||||
|
|
||||||
|
public static int test11 = 1000;
|
||||||
|
public static String result11 = "8203e8";
|
||||||
|
|
||||||
|
public static BigInteger test12 = new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639935");
|
||||||
|
public static String result12 = "a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
|
||||||
|
|
||||||
|
public static BigInteger test13 = new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639936");
|
||||||
|
public static String result13 = "a1010000000000000000000000000000000000000000000000000000000000000000";
|
||||||
|
|
||||||
|
public static Object[] test14 = new Object[]{1, 2, new Object[]{}};
|
||||||
|
public static String result14 = "c30102c0";
|
||||||
|
public static Object[] expected14 = new Object[]{new byte[]{1}, new byte[]{2}, new Object[]{}};
|
||||||
|
|
||||||
|
public static Object[] test15 = new Object[]{new Object[]{new Object[]{}, new Object[]{}}, new Object[]{}};
|
||||||
|
public static String result15 = "c4c2c0c0c0";
|
||||||
|
|
||||||
|
public static Object[] test16 = new Object[]{"zw", new Object[]{4}, "wz"};
|
||||||
|
public static String result16 = "c8827a77c10482777a";
|
||||||
|
public static Object[] expected16 = new Object[]{new byte[]{122, 119}, new Object[]{new byte[]{4}}, new byte[]{119, 122}};
|
||||||
|
}
|
|
@ -0,0 +1,90 @@
|
||||||
|
package org.ethereum.util;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.spongycastle.util.Arrays;
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Roman Mandeleil
|
||||||
|
* @since 17.05.14
|
||||||
|
*/
|
||||||
|
public class UtilsTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetValueShortString1() {
|
||||||
|
|
||||||
|
String expected = "123·(10^24)";
|
||||||
|
String result = Utils.getValueShortString(new BigInteger("123456789123445654363653463"));
|
||||||
|
|
||||||
|
assertEquals(expected, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetValueShortString2() {
|
||||||
|
|
||||||
|
String expected = "123·(10^3)";
|
||||||
|
String result = Utils.getValueShortString(new BigInteger("123456"));
|
||||||
|
|
||||||
|
assertEquals(expected, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetValueShortString3() {
|
||||||
|
|
||||||
|
String expected = "1·(10^3)";
|
||||||
|
String result = Utils.getValueShortString(new BigInteger("1234"));
|
||||||
|
|
||||||
|
assertEquals(expected, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetValueShortString4() {
|
||||||
|
|
||||||
|
String expected = "123·(10^0)";
|
||||||
|
String result = Utils.getValueShortString(new BigInteger("123"));
|
||||||
|
|
||||||
|
assertEquals(expected, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetValueShortString5() {
|
||||||
|
|
||||||
|
byte[] decimal = Hex.decode("3913517ebd3c0c65000000");
|
||||||
|
String expected = "69·(10^24)";
|
||||||
|
String result = Utils.getValueShortString(new BigInteger(decimal));
|
||||||
|
|
||||||
|
assertEquals(expected, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddressStringToBytes() {
|
||||||
|
// valid address
|
||||||
|
String HexStr = "6c386a4b26f73c802f34673f7248bb118f97424a";
|
||||||
|
byte[] expected = Hex.decode(HexStr);
|
||||||
|
byte[] result = Utils.addressStringToBytes(HexStr);
|
||||||
|
assertEquals(Arrays.areEqual(expected, result), true);
|
||||||
|
|
||||||
|
// invalid address, we removed the last char so it cannot decode
|
||||||
|
HexStr = "6c386a4b26f73c802f34673f7248bb118f97424";
|
||||||
|
expected = null;
|
||||||
|
result = Utils.addressStringToBytes(HexStr);
|
||||||
|
assertEquals(expected, result);
|
||||||
|
|
||||||
|
// invalid address, longer than 20 bytes
|
||||||
|
HexStr = new String(Hex.encode("I am longer than 20 bytes, i promise".getBytes()));
|
||||||
|
expected = null;
|
||||||
|
result = Utils.addressStringToBytes(HexStr);
|
||||||
|
assertEquals(expected, result);
|
||||||
|
|
||||||
|
// invalid address, shorter than 20 bytes
|
||||||
|
HexStr = new String(Hex.encode("I am short".getBytes()));
|
||||||
|
expected = null;
|
||||||
|
result = Utils.addressStringToBytes(HexStr);
|
||||||
|
assertEquals(expected, result);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
package org.ethereum.util;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
public class ValueTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCmp() {
|
||||||
|
Value val1 = new Value("hello");
|
||||||
|
Value val2 = new Value("world");
|
||||||
|
|
||||||
|
assertFalse("Expected values not to be equal", val1.cmp(val2));
|
||||||
|
|
||||||
|
Value val3 = new Value("hello");
|
||||||
|
Value val4 = new Value("hello");
|
||||||
|
|
||||||
|
assertTrue("Expected values to be equal", val3.cmp(val4));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTypes() {
|
||||||
|
Value str = new Value("str");
|
||||||
|
assertEquals(str.asString(), "str");
|
||||||
|
|
||||||
|
Value num = new Value(1);
|
||||||
|
assertEquals(num.asInt(), 1);
|
||||||
|
|
||||||
|
Value inter = new Value(new Object[]{1});
|
||||||
|
Object[] interExp = new Object[]{1};
|
||||||
|
assertTrue(new Value(inter.asObj()).cmp(new Value(interExp)));
|
||||||
|
|
||||||
|
Value byt = new Value(new byte[]{1, 2, 3, 4});
|
||||||
|
byte[] bytExp = new byte[]{1, 2, 3, 4};
|
||||||
|
assertTrue(Arrays.equals(byt.asBytes(), bytExp));
|
||||||
|
|
||||||
|
Value bigInt = new Value(BigInteger.valueOf(10));
|
||||||
|
BigInteger bigExp = BigInteger.valueOf(10);
|
||||||
|
assertEquals(bigInt.asBigInt(), bigExp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void longListRLPBug_1() {
|
||||||
|
|
||||||
|
String testRlp = "f7808080d387206f72726563748a626574656c676575736580d387207870726573738a70726564696361626c658080808080808080808080";
|
||||||
|
|
||||||
|
Value val = Value.fromRlpEncoded(Hex.decode(testRlp));
|
||||||
|
|
||||||
|
assertEquals(testRlp, Hex.toHexString(val.encode()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,322 @@
|
||||||
|
package org.ethereum.vm;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
public class DataWordTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddPerformance() {
|
||||||
|
boolean enabled = false;
|
||||||
|
|
||||||
|
if (enabled) {
|
||||||
|
byte[] one = new byte[]{0x01, 0x31, 0x54, 0x41, 0x01, 0x31, 0x54,
|
||||||
|
0x41, 0x01, 0x31, 0x54, 0x41, 0x01, 0x31, 0x54, 0x41, 0x01,
|
||||||
|
0x31, 0x54, 0x41, 0x01, 0x31, 0x54, 0x41, 0x01, 0x31, 0x54,
|
||||||
|
0x41, 0x01, 0x31, 0x54, 0x41}; // Random value
|
||||||
|
|
||||||
|
int ITERATIONS = 10000000;
|
||||||
|
|
||||||
|
long now1 = System.currentTimeMillis();
|
||||||
|
for (int i = 0; i < ITERATIONS; i++) {
|
||||||
|
DataWord x = new DataWord(one);
|
||||||
|
x.add(x);
|
||||||
|
}
|
||||||
|
System.out.println("Add1: " + (System.currentTimeMillis() - now1) + "ms");
|
||||||
|
|
||||||
|
long now2 = System.currentTimeMillis();
|
||||||
|
for (int i = 0; i < ITERATIONS; i++) {
|
||||||
|
DataWord x = new DataWord(one);
|
||||||
|
x.add2(x);
|
||||||
|
}
|
||||||
|
System.out.println("Add2: " + (System.currentTimeMillis() - now2) + "ms");
|
||||||
|
} else {
|
||||||
|
System.out.println("ADD performance test is disabled.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAdd2() {
|
||||||
|
byte[] two = new byte[32];
|
||||||
|
two[31] = (byte) 0xff; // 0x000000000000000000000000000000000000000000000000000000000000ff
|
||||||
|
|
||||||
|
DataWord x = new DataWord(two);
|
||||||
|
x.add(new DataWord(two));
|
||||||
|
System.out.println(Hex.toHexString(x.getData()));
|
||||||
|
|
||||||
|
DataWord y = new DataWord(two);
|
||||||
|
y.add2(new DataWord(two));
|
||||||
|
System.out.println(Hex.toHexString(y.getData()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAdd3() {
|
||||||
|
byte[] three = new byte[32];
|
||||||
|
for (int i = 0; i < three.length; i++) {
|
||||||
|
three[i] = (byte) 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
DataWord x = new DataWord(three);
|
||||||
|
x.add(new DataWord(three));
|
||||||
|
assertEquals(32, x.getData().length);
|
||||||
|
System.out.println(Hex.toHexString(x.getData()));
|
||||||
|
|
||||||
|
// FAIL
|
||||||
|
// DataWord y = new DataWord(three);
|
||||||
|
// y.add2(new DataWord(three));
|
||||||
|
// System.out.println(Hex.toHexString(y.getData()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMod() {
|
||||||
|
String expected = "000000000000000000000000000000000000000000000000000000000000001a";
|
||||||
|
|
||||||
|
byte[] one = new byte[32];
|
||||||
|
one[31] = 0x1e; // 0x000000000000000000000000000000000000000000000000000000000000001e
|
||||||
|
|
||||||
|
byte[] two = new byte[32];
|
||||||
|
for (int i = 0; i < two.length; i++) {
|
||||||
|
two[i] = (byte) 0xff;
|
||||||
|
}
|
||||||
|
two[31] = 0x56; // 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff56
|
||||||
|
|
||||||
|
DataWord x = new DataWord(one);// System.out.println(x.value());
|
||||||
|
DataWord y = new DataWord(two);// System.out.println(y.value());
|
||||||
|
y.mod(x);
|
||||||
|
assertEquals(32, y.getData().length);
|
||||||
|
assertEquals(expected, Hex.toHexString(y.getData()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMul() {
|
||||||
|
byte[] one = new byte[32];
|
||||||
|
one[31] = 0x1; // 0x0000000000000000000000000000000000000000000000000000000000000001
|
||||||
|
|
||||||
|
byte[] two = new byte[32];
|
||||||
|
two[11] = 0x1; // 0x0000000000000000000000010000000000000000000000000000000000000000
|
||||||
|
|
||||||
|
DataWord x = new DataWord(one);// System.out.println(x.value());
|
||||||
|
DataWord y = new DataWord(two);// System.out.println(y.value());
|
||||||
|
x.mul(y);
|
||||||
|
assertEquals(32, y.getData().length);
|
||||||
|
assertEquals("0000000000000000000000010000000000000000000000000000000000000000", Hex.toHexString(y.getData()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMulOverflow() {
|
||||||
|
|
||||||
|
byte[] one = new byte[32];
|
||||||
|
one[30] = 0x1; // 0x0000000000000000000000000000000000000000000000000000000000000100
|
||||||
|
|
||||||
|
byte[] two = new byte[32];
|
||||||
|
two[0] = 0x1; // 0x1000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
|
||||||
|
DataWord x = new DataWord(one);// System.out.println(x.value());
|
||||||
|
DataWord y = new DataWord(two);// System.out.println(y.value());
|
||||||
|
x.mul(y);
|
||||||
|
assertEquals(32, y.getData().length);
|
||||||
|
assertEquals("0100000000000000000000000000000000000000000000000000000000000000", Hex.toHexString(y.getData()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDiv() {
|
||||||
|
byte[] one = new byte[32];
|
||||||
|
one[30] = 0x01;
|
||||||
|
one[31] = 0x2c; // 0x000000000000000000000000000000000000000000000000000000000000012c
|
||||||
|
|
||||||
|
byte[] two = new byte[32];
|
||||||
|
two[31] = 0x0f; // 0x000000000000000000000000000000000000000000000000000000000000000f
|
||||||
|
|
||||||
|
DataWord x = new DataWord(one);
|
||||||
|
DataWord y = new DataWord(two);
|
||||||
|
x.div(y);
|
||||||
|
|
||||||
|
assertEquals(32, x.getData().length);
|
||||||
|
assertEquals("0000000000000000000000000000000000000000000000000000000000000014", Hex.toHexString(x.getData()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDivZero() {
|
||||||
|
byte[] one = new byte[32];
|
||||||
|
one[30] = 0x05; // 0x0000000000000000000000000000000000000000000000000000000000000500
|
||||||
|
|
||||||
|
byte[] two = new byte[32];
|
||||||
|
|
||||||
|
DataWord x = new DataWord(one);
|
||||||
|
DataWord y = new DataWord(two);
|
||||||
|
x.div(y);
|
||||||
|
|
||||||
|
assertEquals(32, x.getData().length);
|
||||||
|
assertTrue(x.isZero());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSDivNegative() {
|
||||||
|
|
||||||
|
// one is -300 as 256-bit signed integer:
|
||||||
|
byte[] one = Hex.decode("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed4");
|
||||||
|
|
||||||
|
byte[] two = new byte[32];
|
||||||
|
two[31] = 0x0f;
|
||||||
|
|
||||||
|
DataWord x = new DataWord(one);
|
||||||
|
DataWord y = new DataWord(two);
|
||||||
|
x.sDiv(y);
|
||||||
|
|
||||||
|
assertEquals(32, x.getData().length);
|
||||||
|
assertEquals("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec", x.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPow() {
|
||||||
|
|
||||||
|
BigInteger x = BigInteger.valueOf(Integer.MAX_VALUE);
|
||||||
|
BigInteger y = BigInteger.valueOf(1000);
|
||||||
|
|
||||||
|
BigInteger result1 = x.modPow(x, y);
|
||||||
|
BigInteger result2 = pow(x, y);
|
||||||
|
System.out.println(result1);
|
||||||
|
System.out.println(result2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSignExtend1() {
|
||||||
|
|
||||||
|
DataWord x = new DataWord(Hex.decode("f2"));
|
||||||
|
byte k = 0;
|
||||||
|
String expected = "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2";
|
||||||
|
|
||||||
|
x.signExtend(k);
|
||||||
|
System.out.println(x.toString());
|
||||||
|
assertEquals(expected, x.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSignExtend2() {
|
||||||
|
DataWord x = new DataWord(Hex.decode("f2"));
|
||||||
|
byte k = 1;
|
||||||
|
String expected = "00000000000000000000000000000000000000000000000000000000000000f2";
|
||||||
|
|
||||||
|
x.signExtend(k);
|
||||||
|
System.out.println(x.toString());
|
||||||
|
assertEquals(expected, x.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSignExtend3() {
|
||||||
|
|
||||||
|
byte k = 1;
|
||||||
|
DataWord x = new DataWord(Hex.decode("0f00ab"));
|
||||||
|
String expected = "00000000000000000000000000000000000000000000000000000000000000ab";
|
||||||
|
|
||||||
|
x.signExtend(k);
|
||||||
|
System.out.println(x.toString());
|
||||||
|
assertEquals(expected, x.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSignExtend4() {
|
||||||
|
|
||||||
|
byte k = 1;
|
||||||
|
DataWord x = new DataWord(Hex.decode("ffff"));
|
||||||
|
String expected = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
|
||||||
|
|
||||||
|
x.signExtend(k);
|
||||||
|
System.out.println(x.toString());
|
||||||
|
assertEquals(expected, x.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSignExtend5() {
|
||||||
|
|
||||||
|
byte k = 3;
|
||||||
|
DataWord x = new DataWord(Hex.decode("ffffffff"));
|
||||||
|
String expected = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
|
||||||
|
|
||||||
|
x.signExtend(k);
|
||||||
|
System.out.println(x.toString());
|
||||||
|
assertEquals(expected, x.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSignExtend6() {
|
||||||
|
|
||||||
|
byte k = 3;
|
||||||
|
DataWord x = new DataWord(Hex.decode("ab02345678"));
|
||||||
|
String expected = "0000000000000000000000000000000000000000000000000000000002345678";
|
||||||
|
|
||||||
|
x.signExtend(k);
|
||||||
|
System.out.println(x.toString());
|
||||||
|
assertEquals(expected, x.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSignExtend7() {
|
||||||
|
|
||||||
|
byte k = 3;
|
||||||
|
DataWord x = new DataWord(Hex.decode("ab82345678"));
|
||||||
|
String expected = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff82345678";
|
||||||
|
|
||||||
|
x.signExtend(k);
|
||||||
|
System.out.println(x.toString());
|
||||||
|
assertEquals(expected, x.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSignExtend8() {
|
||||||
|
|
||||||
|
byte k = 30;
|
||||||
|
DataWord x = new DataWord(Hex.decode("ff34567882345678823456788234567882345678823456788234567882345678"));
|
||||||
|
String expected = "0034567882345678823456788234567882345678823456788234567882345678";
|
||||||
|
|
||||||
|
x.signExtend(k);
|
||||||
|
System.out.println(x.toString());
|
||||||
|
assertEquals(expected, x.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IndexOutOfBoundsException.class)
|
||||||
|
public void testSignExtendException1() {
|
||||||
|
|
||||||
|
byte k = -1;
|
||||||
|
DataWord x = new DataWord();
|
||||||
|
|
||||||
|
x.signExtend(k); // should throw an exception
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IndexOutOfBoundsException.class)
|
||||||
|
public void testSignExtendException2() {
|
||||||
|
|
||||||
|
byte k = 32;
|
||||||
|
DataWord x = new DataWord();
|
||||||
|
|
||||||
|
x.signExtend(k); // should throw an exception
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BigInteger pow(BigInteger x, BigInteger y) {
|
||||||
|
if (y.compareTo(BigInteger.ZERO) < 0)
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
BigInteger z = x; // z will successively become x^2, x^4, x^8, x^16,
|
||||||
|
// x^32...
|
||||||
|
BigInteger result = BigInteger.ONE;
|
||||||
|
byte[] bytes = y.toByteArray();
|
||||||
|
for (int i = bytes.length - 1; i >= 0; i--) {
|
||||||
|
byte bits = bytes[i];
|
||||||
|
for (int j = 0; j < 8; j++) {
|
||||||
|
if ((bits & 1) != 0)
|
||||||
|
result = result.multiply(z);
|
||||||
|
// short cut out if there are no more bits to handle:
|
||||||
|
if ((bits >>= 1) == 0 && i == 0)
|
||||||
|
return result;
|
||||||
|
z = z.multiply(z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,424 @@
|
||||||
|
package org.ethereum.vm;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import static java.lang.Math.ceil;
|
||||||
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class MemoryTest {
|
||||||
|
|
||||||
|
private static final int WORD_SIZE = 32;
|
||||||
|
private static final int CHUNK_SIZE = 1024;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExtend() {
|
||||||
|
checkMemoryExtend(0);
|
||||||
|
checkMemoryExtend(1);
|
||||||
|
checkMemoryExtend(WORD_SIZE);
|
||||||
|
checkMemoryExtend(WORD_SIZE * 2);
|
||||||
|
checkMemoryExtend(CHUNK_SIZE - 1);
|
||||||
|
checkMemoryExtend(CHUNK_SIZE);
|
||||||
|
checkMemoryExtend(CHUNK_SIZE + 1);
|
||||||
|
checkMemoryExtend(2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void checkMemoryExtend(int dataSize) {
|
||||||
|
Memory memory = new Memory();
|
||||||
|
memory.extend(0, dataSize);
|
||||||
|
assertEquals(calcSize(dataSize, CHUNK_SIZE), memory.internalSize());
|
||||||
|
assertEquals(calcSize(dataSize, WORD_SIZE), memory.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int calcSize(int dataSize, int chunkSize) {
|
||||||
|
return (int) ceil((double) dataSize / chunkSize) * chunkSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void memorySave_1() {
|
||||||
|
|
||||||
|
Memory memoryBuffer = new Memory();
|
||||||
|
byte[] data = {1, 1, 1, 1};
|
||||||
|
|
||||||
|
memoryBuffer.write(0, data);
|
||||||
|
|
||||||
|
Assert.assertTrue(1 == memoryBuffer.getChunks().size());
|
||||||
|
|
||||||
|
byte[] chunk = memoryBuffer.getChunks().get(0);
|
||||||
|
Assert.assertTrue(chunk[0] == 1);
|
||||||
|
Assert.assertTrue(chunk[1] == 1);
|
||||||
|
Assert.assertTrue(chunk[2] == 1);
|
||||||
|
Assert.assertTrue(chunk[3] == 1);
|
||||||
|
Assert.assertTrue(chunk[4] == 0);
|
||||||
|
|
||||||
|
Assert.assertTrue(memoryBuffer.size() == 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void memorySave_2() {
|
||||||
|
|
||||||
|
Memory memoryBuffer = new Memory();
|
||||||
|
byte[] data = Hex.decode("0101010101010101010101010101010101010101010101010101010101010101");
|
||||||
|
|
||||||
|
memoryBuffer.write(0, data);
|
||||||
|
|
||||||
|
Assert.assertTrue(1 == memoryBuffer.getChunks().size());
|
||||||
|
|
||||||
|
byte[] chunk = memoryBuffer.getChunks().get(0);
|
||||||
|
Assert.assertTrue(chunk[0] == 1);
|
||||||
|
Assert.assertTrue(chunk[1] == 1);
|
||||||
|
|
||||||
|
Assert.assertTrue(chunk[30] == 1);
|
||||||
|
Assert.assertTrue(chunk[31] == 1);
|
||||||
|
Assert.assertTrue(chunk[32] == 0);
|
||||||
|
|
||||||
|
Assert.assertTrue(memoryBuffer.size() == 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void memorySave_3() {
|
||||||
|
|
||||||
|
Memory memoryBuffer = new Memory();
|
||||||
|
byte[] data = Hex.decode("010101010101010101010101010101010101010101010101010101010101010101");
|
||||||
|
|
||||||
|
memoryBuffer.write(0, data);
|
||||||
|
|
||||||
|
Assert.assertTrue(1 == memoryBuffer.getChunks().size());
|
||||||
|
|
||||||
|
byte[] chunk = memoryBuffer.getChunks().get(0);
|
||||||
|
Assert.assertTrue(chunk[0] == 1);
|
||||||
|
Assert.assertTrue(chunk[1] == 1);
|
||||||
|
|
||||||
|
Assert.assertTrue(chunk[30] == 1);
|
||||||
|
Assert.assertTrue(chunk[31] == 1);
|
||||||
|
Assert.assertTrue(chunk[32] == 1);
|
||||||
|
Assert.assertTrue(chunk[33] == 0);
|
||||||
|
|
||||||
|
Assert.assertTrue(memoryBuffer.size() == 64);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void memorySave_4() {
|
||||||
|
|
||||||
|
Memory memoryBuffer = new Memory();
|
||||||
|
byte[] data = new byte[1024];
|
||||||
|
Arrays.fill(data, (byte) 1);
|
||||||
|
|
||||||
|
memoryBuffer.write(0, data);
|
||||||
|
|
||||||
|
Assert.assertTrue(1 == memoryBuffer.getChunks().size());
|
||||||
|
|
||||||
|
byte[] chunk = memoryBuffer.getChunks().get(0);
|
||||||
|
Assert.assertTrue(chunk[0] == 1);
|
||||||
|
Assert.assertTrue(chunk[1] == 1);
|
||||||
|
|
||||||
|
Assert.assertTrue(chunk[1022] == 1);
|
||||||
|
Assert.assertTrue(chunk[1023] == 1);
|
||||||
|
|
||||||
|
Assert.assertTrue(memoryBuffer.size() == 1024);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void memorySave_5() {
|
||||||
|
|
||||||
|
Memory memoryBuffer = new Memory();
|
||||||
|
|
||||||
|
byte[] data = new byte[1025];
|
||||||
|
Arrays.fill(data, (byte) 1);
|
||||||
|
|
||||||
|
memoryBuffer.write(0, data);
|
||||||
|
|
||||||
|
Assert.assertTrue(2 == memoryBuffer.getChunks().size());
|
||||||
|
|
||||||
|
byte[] chunk1 = memoryBuffer.getChunks().get(0);
|
||||||
|
Assert.assertTrue(chunk1[0] == 1);
|
||||||
|
Assert.assertTrue(chunk1[1] == 1);
|
||||||
|
|
||||||
|
Assert.assertTrue(chunk1[1022] == 1);
|
||||||
|
Assert.assertTrue(chunk1[1023] == 1);
|
||||||
|
|
||||||
|
byte[] chunk2 = memoryBuffer.getChunks().get(1);
|
||||||
|
Assert.assertTrue(chunk2[0] == 1);
|
||||||
|
Assert.assertTrue(chunk2[1] == 0);
|
||||||
|
|
||||||
|
Assert.assertTrue(memoryBuffer.size() == 1056);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void memorySave_6() {
|
||||||
|
|
||||||
|
Memory memoryBuffer = new Memory();
|
||||||
|
|
||||||
|
byte[] data1 = new byte[1024];
|
||||||
|
Arrays.fill(data1, (byte) 1);
|
||||||
|
|
||||||
|
byte[] data2 = new byte[1024];
|
||||||
|
Arrays.fill(data2, (byte) 2);
|
||||||
|
|
||||||
|
memoryBuffer.write(0, data1);
|
||||||
|
memoryBuffer.write(1024, data2);
|
||||||
|
|
||||||
|
Assert.assertTrue(2 == memoryBuffer.getChunks().size());
|
||||||
|
|
||||||
|
byte[] chunk1 = memoryBuffer.getChunks().get(0);
|
||||||
|
Assert.assertTrue(chunk1[0] == 1);
|
||||||
|
Assert.assertTrue(chunk1[1] == 1);
|
||||||
|
|
||||||
|
Assert.assertTrue(chunk1[1022] == 1);
|
||||||
|
Assert.assertTrue(chunk1[1023] == 1);
|
||||||
|
|
||||||
|
byte[] chunk2 = memoryBuffer.getChunks().get(1);
|
||||||
|
Assert.assertTrue(chunk2[0] == 2);
|
||||||
|
Assert.assertTrue(chunk2[1] == 2);
|
||||||
|
|
||||||
|
Assert.assertTrue(chunk2[1022] == 2);
|
||||||
|
Assert.assertTrue(chunk2[1023] == 2);
|
||||||
|
|
||||||
|
Assert.assertTrue(memoryBuffer.size() == 2048);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void memorySave_7() {
|
||||||
|
|
||||||
|
Memory memoryBuffer = new Memory();
|
||||||
|
|
||||||
|
byte[] data1 = new byte[1024];
|
||||||
|
Arrays.fill(data1, (byte) 1);
|
||||||
|
|
||||||
|
byte[] data2 = new byte[1024];
|
||||||
|
Arrays.fill(data2, (byte) 2);
|
||||||
|
|
||||||
|
byte[] data3 = new byte[1];
|
||||||
|
Arrays.fill(data3, (byte) 3);
|
||||||
|
|
||||||
|
memoryBuffer.write(0, data1);
|
||||||
|
memoryBuffer.write(1024, data2);
|
||||||
|
memoryBuffer.write(2048, data3);
|
||||||
|
|
||||||
|
Assert.assertTrue(3 == memoryBuffer.getChunks().size());
|
||||||
|
|
||||||
|
byte[] chunk1 = memoryBuffer.getChunks().get(0);
|
||||||
|
Assert.assertTrue(chunk1[0] == 1);
|
||||||
|
Assert.assertTrue(chunk1[1] == 1);
|
||||||
|
|
||||||
|
Assert.assertTrue(chunk1[1022] == 1);
|
||||||
|
Assert.assertTrue(chunk1[1023] == 1);
|
||||||
|
|
||||||
|
byte[] chunk2 = memoryBuffer.getChunks().get(1);
|
||||||
|
Assert.assertTrue(chunk2[0] == 2);
|
||||||
|
Assert.assertTrue(chunk2[1] == 2);
|
||||||
|
|
||||||
|
Assert.assertTrue(chunk2[1022] == 2);
|
||||||
|
Assert.assertTrue(chunk2[1023] == 2);
|
||||||
|
|
||||||
|
byte[] chunk3 = memoryBuffer.getChunks().get(2);
|
||||||
|
Assert.assertTrue(chunk3[0] == 3);
|
||||||
|
|
||||||
|
Assert.assertTrue(memoryBuffer.size() == 2080);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void memorySave_8() {
|
||||||
|
|
||||||
|
Memory memoryBuffer = new Memory();
|
||||||
|
|
||||||
|
byte[] data1 = new byte[128];
|
||||||
|
Arrays.fill(data1, (byte) 1);
|
||||||
|
|
||||||
|
memoryBuffer.extendAndWrite(0, 256, data1);
|
||||||
|
|
||||||
|
int ones = 0; int zeroes = 0;
|
||||||
|
for (int i = 0; i < memoryBuffer.size(); ++i){
|
||||||
|
if (memoryBuffer.readByte(i) == 1) ++ones;
|
||||||
|
if (memoryBuffer.readByte(i) == 0) ++zeroes;
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.assertTrue(ones == zeroes);
|
||||||
|
Assert.assertTrue(256 == memoryBuffer.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void memoryLoad_1() {
|
||||||
|
|
||||||
|
Memory memoryBuffer = new Memory();
|
||||||
|
DataWord value = memoryBuffer.readWord(100);
|
||||||
|
Assert.assertTrue(value.intValue() == 0);
|
||||||
|
Assert.assertTrue(memoryBuffer.getChunks().size() == 1);
|
||||||
|
Assert.assertTrue(memoryBuffer.size() == 32 * 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void memoryLoad_2() {
|
||||||
|
|
||||||
|
Memory memoryBuffer = new Memory();
|
||||||
|
DataWord value = memoryBuffer.readWord(2015);
|
||||||
|
Assert.assertTrue(value.intValue() == 0);
|
||||||
|
Assert.assertTrue(memoryBuffer.getChunks().size() == 2);
|
||||||
|
Assert.assertTrue(memoryBuffer.size() == 2048);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void memoryLoad_3() {
|
||||||
|
|
||||||
|
Memory memoryBuffer = new Memory();
|
||||||
|
DataWord value = memoryBuffer.readWord(2016);
|
||||||
|
Assert.assertTrue(value.intValue() == 0);
|
||||||
|
Assert.assertTrue(memoryBuffer.getChunks().size() == 2);
|
||||||
|
Assert.assertTrue(memoryBuffer.size() == 2048);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void memoryLoad_4() {
|
||||||
|
|
||||||
|
Memory memoryBuffer = new Memory();
|
||||||
|
DataWord value = memoryBuffer.readWord(2017);
|
||||||
|
Assert.assertTrue(value.intValue() == 0);
|
||||||
|
Assert.assertTrue(memoryBuffer.getChunks().size() == 3);
|
||||||
|
Assert.assertTrue(memoryBuffer.size() == 2080);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void memoryLoad_5() {
|
||||||
|
|
||||||
|
Memory memoryBuffer = new Memory();
|
||||||
|
|
||||||
|
byte[] data1 = new byte[1024];
|
||||||
|
Arrays.fill(data1, (byte) 1);
|
||||||
|
|
||||||
|
byte[] data2 = new byte[1024];
|
||||||
|
Arrays.fill(data2, (byte) 2);
|
||||||
|
|
||||||
|
memoryBuffer.write(0, data1);
|
||||||
|
memoryBuffer.write(1024, data2);
|
||||||
|
|
||||||
|
Assert.assertTrue(memoryBuffer.getChunks().size() == 2);
|
||||||
|
Assert.assertTrue(memoryBuffer.size() == 2048);
|
||||||
|
|
||||||
|
DataWord val1 = memoryBuffer.readWord(0x3df);
|
||||||
|
DataWord val2 = memoryBuffer.readWord(0x3e0);
|
||||||
|
DataWord val3 = memoryBuffer.readWord(0x3e1);
|
||||||
|
|
||||||
|
assertArrayEquals(
|
||||||
|
Hex.decode("0101010101010101010101010101010101010101010101010101010101010101"),
|
||||||
|
val1.getData());
|
||||||
|
|
||||||
|
assertArrayEquals(
|
||||||
|
Hex.decode("0101010101010101010101010101010101010101010101010101010101010101"),
|
||||||
|
val2.getData());
|
||||||
|
|
||||||
|
assertArrayEquals(
|
||||||
|
Hex.decode("0101010101010101010101010101010101010101010101010101010101010102"),
|
||||||
|
val3.getData());
|
||||||
|
Assert.assertTrue(memoryBuffer.size() == 2048);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void memoryChunk_1(){
|
||||||
|
Memory memoryBuffer = new Memory();
|
||||||
|
|
||||||
|
byte[] data1 = new byte[32];
|
||||||
|
Arrays.fill(data1, (byte) 1);
|
||||||
|
|
||||||
|
byte[] data2 = new byte[32];
|
||||||
|
Arrays.fill(data2, (byte) 2);
|
||||||
|
|
||||||
|
memoryBuffer.write(0, data1);
|
||||||
|
memoryBuffer.write(32, data2);
|
||||||
|
|
||||||
|
byte[] data = memoryBuffer.read(0, 64);
|
||||||
|
|
||||||
|
assertArrayEquals(
|
||||||
|
Hex.decode("0101010101010101010101010101010101010101010101010101010101010101" +
|
||||||
|
"0202020202020202020202020202020202020202020202020202020202020202"),
|
||||||
|
data
|
||||||
|
);
|
||||||
|
|
||||||
|
assertEquals(64, memoryBuffer.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void memoryChunk_2(){
|
||||||
|
Memory memoryBuffer = new Memory();
|
||||||
|
|
||||||
|
byte[] data1 = new byte[32];
|
||||||
|
Arrays.fill(data1, (byte) 1);
|
||||||
|
|
||||||
|
memoryBuffer.write(0, data1);
|
||||||
|
Assert.assertTrue(32 == memoryBuffer.size());
|
||||||
|
|
||||||
|
byte[] data = memoryBuffer.read(0, 64);
|
||||||
|
|
||||||
|
assertArrayEquals(
|
||||||
|
Hex.decode("0101010101010101010101010101010101010101010101010101010101010101" +
|
||||||
|
"0000000000000000000000000000000000000000000000000000000000000000"),
|
||||||
|
data
|
||||||
|
);
|
||||||
|
|
||||||
|
assertEquals(64, memoryBuffer.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void memoryChunk_3(){
|
||||||
|
|
||||||
|
Memory memoryBuffer = new Memory();
|
||||||
|
|
||||||
|
byte[] data1 = new byte[1024];
|
||||||
|
Arrays.fill(data1, (byte) 1);
|
||||||
|
|
||||||
|
byte[] data2 = new byte[1024];
|
||||||
|
Arrays.fill(data2, (byte) 2);
|
||||||
|
|
||||||
|
memoryBuffer.write(0, data1);
|
||||||
|
memoryBuffer.write(1024, data2);
|
||||||
|
|
||||||
|
byte[] data = memoryBuffer.read(0, 2048);
|
||||||
|
|
||||||
|
int ones = 0; int twos = 0;
|
||||||
|
for (int i = 0; i < data.length; ++i){
|
||||||
|
if (data[i] == 1) ++ones;
|
||||||
|
if (data[i] == 2) ++twos;
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.assertTrue(ones == twos);
|
||||||
|
Assert.assertTrue(2048 == memoryBuffer.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void memoryChunk_4(){
|
||||||
|
|
||||||
|
Memory memoryBuffer = new Memory();
|
||||||
|
|
||||||
|
byte[] data1 = new byte[1024];
|
||||||
|
Arrays.fill(data1, (byte) 1);
|
||||||
|
|
||||||
|
byte[] data2 = new byte[1024];
|
||||||
|
Arrays.fill(data2, (byte) 2);
|
||||||
|
|
||||||
|
memoryBuffer.write(0, data1);
|
||||||
|
memoryBuffer.write(1024, data2);
|
||||||
|
|
||||||
|
byte[] data = memoryBuffer.read(0, 2049);
|
||||||
|
|
||||||
|
int ones = 0; int twos = 0; int zero = 0;
|
||||||
|
for (int i = 0; i < data.length; ++i){
|
||||||
|
if (data[i] == 1) ++ones;
|
||||||
|
if (data[i] == 2) ++twos;
|
||||||
|
if (data[i] == 0) ++zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.assertTrue(zero == 1);
|
||||||
|
Assert.assertTrue(ones == twos);
|
||||||
|
Assert.assertTrue(2080 == memoryBuffer.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,100 @@
|
||||||
|
package org.ethereum.vm;
|
||||||
|
|
||||||
|
import org.ethereum.util.ByteUtil;
|
||||||
|
import org.ethereum.vm.PrecompiledContracts.PrecompiledContract;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Roman Mandeleil
|
||||||
|
*/
|
||||||
|
public class PrecompiledContractTest {
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void identityTest1() {
|
||||||
|
|
||||||
|
DataWord addr = new DataWord("0000000000000000000000000000000000000000000000000000000000000004");
|
||||||
|
PrecompiledContract contract = PrecompiledContracts.getContractForAddress(addr);
|
||||||
|
byte[] data = Hex.decode("112233445566");
|
||||||
|
byte[] expected = Hex.decode("112233445566");
|
||||||
|
|
||||||
|
byte[] result = contract.execute(data);
|
||||||
|
|
||||||
|
assertArrayEquals(expected, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void sha256Test1() {
|
||||||
|
|
||||||
|
DataWord addr = new DataWord("0000000000000000000000000000000000000000000000000000000000000002");
|
||||||
|
PrecompiledContract contract = PrecompiledContracts.getContractForAddress(addr);
|
||||||
|
byte[] data = null;
|
||||||
|
String expected = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
|
||||||
|
|
||||||
|
byte[] result = contract.execute(data);
|
||||||
|
|
||||||
|
assertEquals(expected, Hex.toHexString(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void sha256Test2() {
|
||||||
|
|
||||||
|
DataWord addr = new DataWord("0000000000000000000000000000000000000000000000000000000000000002");
|
||||||
|
PrecompiledContract contract = PrecompiledContracts.getContractForAddress(addr);
|
||||||
|
byte[] data = ByteUtil.EMPTY_BYTE_ARRAY;
|
||||||
|
String expected = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
|
||||||
|
|
||||||
|
byte[] result = contract.execute(data);
|
||||||
|
|
||||||
|
assertEquals(expected, Hex.toHexString(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void sha256Test3() {
|
||||||
|
|
||||||
|
DataWord addr = new DataWord("0000000000000000000000000000000000000000000000000000000000000002");
|
||||||
|
PrecompiledContract contract = PrecompiledContracts.getContractForAddress(addr);
|
||||||
|
byte[] data = Hex.decode("112233");
|
||||||
|
String expected = "49ee2bf93aac3b1fb4117e59095e07abe555c3383b38d608da37680a406096e8";
|
||||||
|
|
||||||
|
byte[] result = contract.execute(data);
|
||||||
|
|
||||||
|
assertEquals(expected, Hex.toHexString(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void Ripempd160Test1() {
|
||||||
|
|
||||||
|
DataWord addr = new DataWord("0000000000000000000000000000000000000000000000000000000000000003");
|
||||||
|
PrecompiledContract contract = PrecompiledContracts.getContractForAddress(addr);
|
||||||
|
byte[] data = Hex.decode("0000000000000000000000000000000000000000000000000000000000000001");
|
||||||
|
String expected = "000000000000000000000000ae387fcfeb723c3f5964509af111cf5a67f30661";
|
||||||
|
|
||||||
|
byte[] result = contract.execute(data);
|
||||||
|
|
||||||
|
assertEquals(expected, Hex.toHexString(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ecRecoverTest1() {
|
||||||
|
|
||||||
|
byte[] data = Hex.decode("18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c000000000000000000000000000000000000000000000000000000000000001c73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549");
|
||||||
|
DataWord addr = new DataWord("0000000000000000000000000000000000000000000000000000000000000001");
|
||||||
|
PrecompiledContract contract = PrecompiledContracts.getContractForAddress(addr);
|
||||||
|
String expected = "000000000000000000000000ae387fcfeb723c3f5964509af111cf5a67f30661";
|
||||||
|
|
||||||
|
byte[] result = contract.execute(data);
|
||||||
|
|
||||||
|
System.out.println(Hex.toHexString(result));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,336 @@
|
||||||
|
package org.ethereum.vm;
|
||||||
|
|
||||||
|
import org.ethereum.util.ByteUtil;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
public class ProgramMemoryTest {
|
||||||
|
|
||||||
|
ProgramInvokeMockImpl pi = null;
|
||||||
|
Program program;
|
||||||
|
ByteBuffer memory;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void createProgram() {
|
||||||
|
program = new Program(ByteUtil.EMPTY_BYTE_ARRAY, pi);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetMemSize() {
|
||||||
|
byte[] memory = new byte[64];
|
||||||
|
program.initMem(memory);
|
||||||
|
assertEquals(64, program.getMemSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void testMemorySave() {
|
||||||
|
fail("Not yet implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void testMemoryLoad() {
|
||||||
|
fail("Not yet implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMemoryChunk1() {
|
||||||
|
program.initMem(new byte[64]);
|
||||||
|
int offset = 128;
|
||||||
|
int size = 32;
|
||||||
|
program.memoryChunk(offset, size);
|
||||||
|
assertEquals(160, program.getMemSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // size 0 doesn't increase memory
|
||||||
|
public void testMemoryChunk2() {
|
||||||
|
program.initMem(new byte[64]);
|
||||||
|
int offset = 96;
|
||||||
|
int size = 0;
|
||||||
|
program.memoryChunk(offset, size);
|
||||||
|
assertEquals(64, program.getMemSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAllocateMemory1() {
|
||||||
|
|
||||||
|
program.initMem(new byte[64]);
|
||||||
|
int offset = 32;
|
||||||
|
int size = 32;
|
||||||
|
program.allocateMemory(offset, size);
|
||||||
|
assertEquals(64, program.getMemSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAllocateMemory2() {
|
||||||
|
|
||||||
|
// memory.limit() > offset, == size
|
||||||
|
// memory.limit() < offset + size
|
||||||
|
program.initMem(new byte[64]);
|
||||||
|
int offset = 32;
|
||||||
|
int size = 64;
|
||||||
|
program.allocateMemory(offset, size);
|
||||||
|
assertEquals(96, program.getMemSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAllocateMemory3() {
|
||||||
|
|
||||||
|
// memory.limit() > offset, > size
|
||||||
|
program.initMem(new byte[64]);
|
||||||
|
int offset = 0;
|
||||||
|
int size = 32;
|
||||||
|
program.allocateMemory(offset, size);
|
||||||
|
assertEquals(64, program.getMemSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAllocateMemory4() {
|
||||||
|
|
||||||
|
program.initMem(new byte[64]);
|
||||||
|
int offset = 0;
|
||||||
|
int size = 64;
|
||||||
|
program.allocateMemory(offset, size);
|
||||||
|
assertEquals(64, program.getMemSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAllocateMemory5() {
|
||||||
|
|
||||||
|
program.initMem(new byte[64]);
|
||||||
|
int offset = 0;
|
||||||
|
int size = 0;
|
||||||
|
program.allocateMemory(offset, size);
|
||||||
|
assertEquals(64, program.getMemSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAllocateMemory6() {
|
||||||
|
|
||||||
|
// memory.limit() == offset, > size
|
||||||
|
program.initMem(new byte[64]);
|
||||||
|
int offset = 64;
|
||||||
|
int size = 32;
|
||||||
|
program.allocateMemory(offset, size);
|
||||||
|
assertEquals(96, program.getMemSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAllocateMemory7() {
|
||||||
|
|
||||||
|
// memory.limit() == offset - size
|
||||||
|
program.initMem(new byte[64]);
|
||||||
|
int offset = 96;
|
||||||
|
int size = 32;
|
||||||
|
program.allocateMemory(offset, size);
|
||||||
|
assertEquals(128, program.getMemSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAllocateMemory8() {
|
||||||
|
|
||||||
|
program.initMem(new byte[64]);
|
||||||
|
int offset = 0;
|
||||||
|
int size = 96;
|
||||||
|
program.allocateMemory(offset, size);
|
||||||
|
assertEquals(96, program.getMemSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAllocateMemory9() {
|
||||||
|
|
||||||
|
// memory.limit() < offset, > size
|
||||||
|
// memory.limit() < offset - size
|
||||||
|
program.initMem(new byte[64]);
|
||||||
|
int offset = 96;
|
||||||
|
int size = 0;
|
||||||
|
program.allocateMemory(offset, size);
|
||||||
|
assertEquals(64, program.getMemSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAllocateMemory10() {
|
||||||
|
|
||||||
|
// memory = null, offset > size
|
||||||
|
int offset = 32;
|
||||||
|
int size = 0;
|
||||||
|
program.allocateMemory(offset, size);
|
||||||
|
assertEquals(0, program.getMemSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAllocateMemory11() {
|
||||||
|
|
||||||
|
// memory = null, offset < size
|
||||||
|
int offset = 0;
|
||||||
|
int size = 32;
|
||||||
|
program.allocateMemory(offset, size);
|
||||||
|
assertEquals(32, program.getMemSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAllocateMemory12() {
|
||||||
|
|
||||||
|
// memory.limit() < offset, < size
|
||||||
|
program.initMem(new byte[64]);
|
||||||
|
int offset = 64;
|
||||||
|
int size = 96;
|
||||||
|
program.allocateMemory(offset, size);
|
||||||
|
assertEquals(160, program.getMemSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAllocateMemory13() {
|
||||||
|
|
||||||
|
// memory.limit() > offset, < size
|
||||||
|
program.initMem(new byte[64]);
|
||||||
|
int offset = 32;
|
||||||
|
int size = 128;
|
||||||
|
program.allocateMemory(offset, size);
|
||||||
|
assertEquals(160, program.getMemSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAllocateMemory14() {
|
||||||
|
|
||||||
|
// memory.limit() < offset, == size
|
||||||
|
program.initMem(new byte[64]);
|
||||||
|
int offset = 96;
|
||||||
|
int size = 64;
|
||||||
|
program.allocateMemory(offset, size);
|
||||||
|
assertEquals(160, program.getMemSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAllocateMemory15() {
|
||||||
|
|
||||||
|
// memory.limit() == offset, < size
|
||||||
|
program.initMem(new byte[64]);
|
||||||
|
int offset = 64;
|
||||||
|
int size = 96;
|
||||||
|
program.allocateMemory(offset, size);
|
||||||
|
assertEquals(160, program.getMemSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAllocateMemory16() {
|
||||||
|
|
||||||
|
// memory.limit() == offset, == size
|
||||||
|
// memory.limit() > offset - size
|
||||||
|
program.initMem(new byte[64]);
|
||||||
|
int offset = 64;
|
||||||
|
int size = 64;
|
||||||
|
program.allocateMemory(offset, size);
|
||||||
|
assertEquals(128, program.getMemSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAllocateMemory17() {
|
||||||
|
|
||||||
|
// memory.limit() > offset + size
|
||||||
|
program.initMem(new byte[96]);
|
||||||
|
int offset = 32;
|
||||||
|
int size = 32;
|
||||||
|
program.allocateMemory(offset, size);
|
||||||
|
assertEquals(96, program.getMemSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAllocateMemoryUnrounded1() {
|
||||||
|
|
||||||
|
// memory unrounded
|
||||||
|
program.initMem(new byte[64]);
|
||||||
|
int offset = 64;
|
||||||
|
int size = 32;
|
||||||
|
program.allocateMemory(offset, size);
|
||||||
|
assertEquals(96, program.getMemSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAllocateMemoryUnrounded2() {
|
||||||
|
|
||||||
|
// offset unrounded
|
||||||
|
program.initMem(new byte[64]);
|
||||||
|
int offset = 16;
|
||||||
|
int size = 32;
|
||||||
|
program.allocateMemory(offset, size);
|
||||||
|
assertEquals(64, program.getMemSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAllocateMemoryUnrounded3() {
|
||||||
|
|
||||||
|
// size unrounded
|
||||||
|
program.initMem(new byte[64]);
|
||||||
|
int offset = 64;
|
||||||
|
int size = 16;
|
||||||
|
program.allocateMemory(offset, size);
|
||||||
|
assertEquals(96, program.getMemSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAllocateMemoryUnrounded4() {
|
||||||
|
|
||||||
|
// memory + offset unrounded
|
||||||
|
program.initMem(new byte[64]);
|
||||||
|
int offset = 16;
|
||||||
|
int size = 32;
|
||||||
|
program.allocateMemory(offset, size);
|
||||||
|
assertEquals(64, program.getMemSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAllocateMemoryUnrounded5() {
|
||||||
|
|
||||||
|
// memory + size unrounded
|
||||||
|
program.initMem(new byte[64]);
|
||||||
|
int offset = 32;
|
||||||
|
int size = 16;
|
||||||
|
program.allocateMemory(offset, size);
|
||||||
|
assertEquals(64, program.getMemSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAllocateMemoryUnrounded6() {
|
||||||
|
|
||||||
|
// offset + size unrounded
|
||||||
|
program.initMem(new byte[32]);
|
||||||
|
int offset = 16;
|
||||||
|
int size = 16;
|
||||||
|
program.allocateMemory(offset, size);
|
||||||
|
assertEquals(32, program.getMemSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAllocateMemoryUnrounded7() {
|
||||||
|
|
||||||
|
// memory + offset + size unrounded
|
||||||
|
program.initMem(new byte[32]);
|
||||||
|
int offset = 16;
|
||||||
|
int size = 16;
|
||||||
|
program.allocateMemory(offset, size);
|
||||||
|
assertEquals(32, program.getMemSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Ignore
|
||||||
|
@Test
|
||||||
|
public void testInitialInsert() {
|
||||||
|
|
||||||
|
|
||||||
|
// todo: fix the array out of bound here
|
||||||
|
int offset = 32;
|
||||||
|
int size = 00;
|
||||||
|
program.memorySave(32, 0, new byte[0]);
|
||||||
|
assertEquals(32, program.getMemSize());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,664 @@
|
||||||
|
package org.ethereum.vm;
|
||||||
|
|
||||||
|
import org.ethereum.core.AccountState;
|
||||||
|
import org.ethereum.crypto.HashUtil;
|
||||||
|
import org.ethereum.facade.Repository;
|
||||||
|
|
||||||
|
import org.junit.FixMethodOrder;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runners.MethodSorters;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Roman Mandeleil
|
||||||
|
* @since 16.06.2014
|
||||||
|
*/
|
||||||
|
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||||
|
public class VMComplexTest {
|
||||||
|
|
||||||
|
private static Logger logger = LoggerFactory.getLogger("TCK-Test");
|
||||||
|
|
||||||
|
@Ignore //TODO #POC9
|
||||||
|
@Test // contract call recursive
|
||||||
|
public void test1() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* #The code will run
|
||||||
|
* ------------------
|
||||||
|
|
||||||
|
a = contract.storage[999]
|
||||||
|
if a > 0:
|
||||||
|
contract.storage[999] = a - 1
|
||||||
|
|
||||||
|
# call to contract: 77045e71a7a2c50903d88e564cd72fab11e82051
|
||||||
|
send((tx.gas / 10 * 8), 0x77045e71a7a2c50903d88e564cd72fab11e82051, 0)
|
||||||
|
else:
|
||||||
|
stop
|
||||||
|
*/
|
||||||
|
|
||||||
|
int expectedGas = 436;
|
||||||
|
|
||||||
|
DataWord key1 = new DataWord(999);
|
||||||
|
DataWord value1 = new DataWord(3);
|
||||||
|
|
||||||
|
// Set contract into Database
|
||||||
|
String callerAddr = "cd2a3d9f938e13cd947ec05abc7fe734df8dd826";
|
||||||
|
String contractAddr = "77045e71a7a2c50903d88e564cd72fab11e82051";
|
||||||
|
String code =
|
||||||
|
"6103e75460005260006000511115630000004c576001600051036103e755600060006000600060007377045e71a7a2c50903d88e564cd72fab11e820516008600a5a0402f1630000004c00565b00";
|
||||||
|
|
||||||
|
byte[] contractAddrB = Hex.decode(contractAddr);
|
||||||
|
byte[] callerAddrB = Hex.decode(callerAddr);
|
||||||
|
byte[] codeB = Hex.decode(code);
|
||||||
|
|
||||||
|
byte[] codeKey = HashUtil.sha3(codeB);
|
||||||
|
AccountState accountState = new AccountState();
|
||||||
|
accountState.setCodeHash(codeKey);
|
||||||
|
|
||||||
|
ProgramInvokeMockImpl pi = new ProgramInvokeMockImpl();
|
||||||
|
pi.setOwnerAddress(contractAddrB);
|
||||||
|
Repository repository = pi.getRepository();
|
||||||
|
|
||||||
|
repository.createAccount(callerAddrB);
|
||||||
|
repository.addBalance(callerAddrB, new BigInteger("100000000000000000000"));
|
||||||
|
|
||||||
|
repository.createAccount(contractAddrB);
|
||||||
|
repository.saveCode(contractAddrB, codeB);
|
||||||
|
repository.addStorageRow(contractAddrB, key1, value1);
|
||||||
|
|
||||||
|
// Play the program
|
||||||
|
VM vm = new VM();
|
||||||
|
Program program = new Program(codeB, pi);
|
||||||
|
|
||||||
|
try {
|
||||||
|
while (!program.isStopped())
|
||||||
|
vm.step(program);
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
program.setRuntimeFailure(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println();
|
||||||
|
System.out.println("============ Results ============");
|
||||||
|
|
||||||
|
BigInteger balance = repository.getBalance(callerAddrB);
|
||||||
|
|
||||||
|
System.out.println("*** Used gas: " + program.getResult().getGasUsed());
|
||||||
|
System.out.println("*** Contract Balance: " + balance);
|
||||||
|
|
||||||
|
// todo: assert caller balance after contract exec
|
||||||
|
|
||||||
|
repository.close();
|
||||||
|
assertEquals(expectedGas, program.getResult().getGasUsed());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Ignore //TODO #POC9
|
||||||
|
@Test // contractB call contractA with data to storage
|
||||||
|
public void test2() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* #The code will run
|
||||||
|
* ------------------
|
||||||
|
|
||||||
|
contract A: 77045e71a7a2c50903d88e564cd72fab11e82051
|
||||||
|
---------------
|
||||||
|
a = msg.data[0]
|
||||||
|
b = msg.data[1]
|
||||||
|
|
||||||
|
contract.storage[a]
|
||||||
|
contract.storage[b]
|
||||||
|
|
||||||
|
|
||||||
|
contract B: 83c5541a6c8d2dbad642f385d8d06ca9b6c731ee
|
||||||
|
-----------
|
||||||
|
a = msg((tx.gas / 10 * 8), 0x77045e71a7a2c50903d88e564cd72fab11e82051, 0, [11, 22, 33], 3, 6)
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
long expectedVal_1 = 11;
|
||||||
|
long expectedVal_2 = 22;
|
||||||
|
|
||||||
|
// Set contract into Database
|
||||||
|
String callerAddr = "cd2a3d9f938e13cd947ec05abc7fe734df8dd826";
|
||||||
|
|
||||||
|
String contractA_addr = "77045e71a7a2c50903d88e564cd72fab11e82051";
|
||||||
|
String contractB_addr = "83c5541a6c8d2dbad642f385d8d06ca9b6c731ee";
|
||||||
|
|
||||||
|
String code_a = "60006020023560005260016020023560205260005160005560205160015500";
|
||||||
|
String code_b = "6000601f5360e05960e05952600060c05901536060596020015980602001600b9052806040016016905280606001602190526080905260007377045e71a7a2c50903d88e564cd72fab11e820516103e8f1602060000260a00160200151600052";
|
||||||
|
|
||||||
|
byte[] caller_addr_bytes = Hex.decode(callerAddr);
|
||||||
|
|
||||||
|
byte[] contractA_addr_bytes = Hex.decode(contractA_addr);
|
||||||
|
byte[] codeA = Hex.decode(code_a);
|
||||||
|
|
||||||
|
byte[] contractB_addr_bytes = Hex.decode(contractB_addr);
|
||||||
|
byte[] codeB = Hex.decode(code_b);
|
||||||
|
|
||||||
|
ProgramInvokeMockImpl pi = new ProgramInvokeMockImpl();
|
||||||
|
pi.setOwnerAddress(contractB_addr_bytes);
|
||||||
|
Repository repository = pi.getRepository();
|
||||||
|
|
||||||
|
repository.createAccount(contractA_addr_bytes);
|
||||||
|
repository.saveCode(contractA_addr_bytes, codeA);
|
||||||
|
|
||||||
|
repository.createAccount(contractB_addr_bytes);
|
||||||
|
repository.saveCode(contractB_addr_bytes, codeB);
|
||||||
|
|
||||||
|
repository.createAccount(caller_addr_bytes);
|
||||||
|
repository.addBalance(caller_addr_bytes, new BigInteger("100000000000000000000"));
|
||||||
|
|
||||||
|
|
||||||
|
// ****************** //
|
||||||
|
// Play the program //
|
||||||
|
// ****************** //
|
||||||
|
VM vm = new VM();
|
||||||
|
Program program = new Program(codeB, pi);
|
||||||
|
|
||||||
|
try {
|
||||||
|
while (!program.isStopped())
|
||||||
|
vm.step(program);
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
program.setRuntimeFailure(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
System.out.println();
|
||||||
|
System.out.println("============ Results ============");
|
||||||
|
|
||||||
|
|
||||||
|
System.out.println("*** Used gas: " + program.getResult().getGasUsed());
|
||||||
|
|
||||||
|
|
||||||
|
DataWord value_1 = repository.getStorageValue(contractA_addr_bytes, new DataWord(00));
|
||||||
|
DataWord value_2 = repository.getStorageValue(contractA_addr_bytes, new DataWord(01));
|
||||||
|
|
||||||
|
|
||||||
|
repository.close();
|
||||||
|
assertEquals(expectedVal_1, value_1.longValue());
|
||||||
|
assertEquals(expectedVal_2, value_2.longValue());
|
||||||
|
|
||||||
|
// TODO: check that the value pushed after exec is 1
|
||||||
|
}
|
||||||
|
|
||||||
|
@Ignore
|
||||||
|
@Test // contractB call contractA with return expectation
|
||||||
|
public void test3() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* #The code will run
|
||||||
|
* ------------------
|
||||||
|
|
||||||
|
contract A: 77045e71a7a2c50903d88e564cd72fab11e82051
|
||||||
|
---------------
|
||||||
|
|
||||||
|
a = 11
|
||||||
|
b = 22
|
||||||
|
c = 33
|
||||||
|
d = 44
|
||||||
|
e = 55
|
||||||
|
f = 66
|
||||||
|
|
||||||
|
[asm 192 0 RETURN asm]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
contract B: 83c5541a6c8d2dbad642f385d8d06ca9b6c731ee
|
||||||
|
-----------
|
||||||
|
a = msg((tx.gas / 10 * 8), 0x77045e71a7a2c50903d88e564cd72fab11e82051, 0, [11, 22, 33], 3, 6)
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
long expectedVal_1 = 11;
|
||||||
|
long expectedVal_2 = 22;
|
||||||
|
long expectedVal_3 = 33;
|
||||||
|
long expectedVal_4 = 44;
|
||||||
|
long expectedVal_5 = 55;
|
||||||
|
long expectedVal_6 = 66;
|
||||||
|
|
||||||
|
// Set contract into Database
|
||||||
|
byte[] caller_addr_bytes = Hex.decode("cd2a3d9f938e13cd947ec05abc7fe734df8dd826");
|
||||||
|
|
||||||
|
byte[] contractA_addr_bytes = Hex.decode("77045e71a7a2c50903d88e564cd72fab11e82051");
|
||||||
|
byte[] contractB_addr_bytes = Hex.decode("83c5541a6c8d2dbad642f385d8d06ca9b6c731ee");
|
||||||
|
|
||||||
|
byte[] codeA = Hex.decode("600b60005260166020526021604052602c6060526037608052604260a05260c06000f2");
|
||||||
|
byte[] codeB = Hex.decode("6000601f5360e05960e05952600060c05901536060596020015980602001600b9052806040016016905280606001602190526080905260007377045e71a7a2c50903d88e564cd72fab11e820516103e8f1602060000260a00160200151600052");
|
||||||
|
|
||||||
|
ProgramInvokeMockImpl pi = new ProgramInvokeMockImpl();
|
||||||
|
pi.setOwnerAddress(contractB_addr_bytes);
|
||||||
|
Repository repository = pi.getRepository();
|
||||||
|
repository.createAccount(contractA_addr_bytes);
|
||||||
|
repository.saveCode(contractA_addr_bytes, codeA);
|
||||||
|
|
||||||
|
repository.createAccount(contractB_addr_bytes);
|
||||||
|
repository.saveCode(contractB_addr_bytes, codeB);
|
||||||
|
|
||||||
|
repository.createAccount(caller_addr_bytes);
|
||||||
|
repository.addBalance(caller_addr_bytes, new BigInteger("100000000000000000000"));
|
||||||
|
|
||||||
|
// ****************** //
|
||||||
|
// Play the program //
|
||||||
|
// ****************** //
|
||||||
|
VM vm = new VM();
|
||||||
|
Program program = new Program(codeB, pi);
|
||||||
|
|
||||||
|
try {
|
||||||
|
while (!program.isStopped())
|
||||||
|
vm.step(program);
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
program.setRuntimeFailure(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println();
|
||||||
|
System.out.println("============ Results ============");
|
||||||
|
System.out.println("*** Used gas: " + program.getResult().getGasUsed());
|
||||||
|
|
||||||
|
DataWord value1 = program.memoryLoad(new DataWord(32));
|
||||||
|
DataWord value2 = program.memoryLoad(new DataWord(64));
|
||||||
|
DataWord value3 = program.memoryLoad(new DataWord(96));
|
||||||
|
DataWord value4 = program.memoryLoad(new DataWord(128));
|
||||||
|
DataWord value5 = program.memoryLoad(new DataWord(160));
|
||||||
|
DataWord value6 = program.memoryLoad(new DataWord(192));
|
||||||
|
|
||||||
|
repository.close();
|
||||||
|
|
||||||
|
assertEquals(expectedVal_1, value1.longValue());
|
||||||
|
assertEquals(expectedVal_2, value2.longValue());
|
||||||
|
assertEquals(expectedVal_3, value3.longValue());
|
||||||
|
assertEquals(expectedVal_4, value4.longValue());
|
||||||
|
assertEquals(expectedVal_5, value5.longValue());
|
||||||
|
assertEquals(expectedVal_6, value6.longValue());
|
||||||
|
|
||||||
|
// TODO: check that the value pushed after exec is 1
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // CREATE magic
|
||||||
|
public void test4() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* #The code will run
|
||||||
|
* ------------------
|
||||||
|
|
||||||
|
contract A: 77045e71a7a2c50903d88e564cd72fab11e82051
|
||||||
|
-----------
|
||||||
|
|
||||||
|
a = 0x7f60c860005461012c6020540000000000000000000000000000000000000000
|
||||||
|
b = 0x0060005460206000f20000000000000000000000000000000000000000000000
|
||||||
|
create(100, 0 41)
|
||||||
|
|
||||||
|
|
||||||
|
contract B: (the contract to be created the addr will be defined to: 8e45367623a2865132d9bf875d5cfa31b9a0cd94)
|
||||||
|
-----------
|
||||||
|
a = 200
|
||||||
|
b = 300
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Set contract into Database
|
||||||
|
byte[] caller_addr_bytes = Hex.decode("cd2a3d9f938e13cd947ec05abc7fe734df8dd826");
|
||||||
|
|
||||||
|
byte[] contractA_addr_bytes = Hex.decode("77045e71a7a2c50903d88e564cd72fab11e82051");
|
||||||
|
|
||||||
|
byte[] codeA = Hex.decode("7f7f60c860005461012c602054000000000000" +
|
||||||
|
"00000000000000000000000000006000547e60" +
|
||||||
|
"005460206000f2000000000000000000000000" +
|
||||||
|
"0000000000000000000000602054602960006064f0");
|
||||||
|
|
||||||
|
ProgramInvokeMockImpl pi = new ProgramInvokeMockImpl();
|
||||||
|
pi.setOwnerAddress(contractA_addr_bytes);
|
||||||
|
|
||||||
|
Repository repository = pi.getRepository();
|
||||||
|
|
||||||
|
repository.createAccount(contractA_addr_bytes);
|
||||||
|
repository.saveCode(contractA_addr_bytes, codeA);
|
||||||
|
|
||||||
|
repository.createAccount(caller_addr_bytes);
|
||||||
|
|
||||||
|
// ****************** //
|
||||||
|
// Play the program //
|
||||||
|
// ****************** //
|
||||||
|
VM vm = new VM();
|
||||||
|
Program program = new Program(codeA, pi);
|
||||||
|
|
||||||
|
try {
|
||||||
|
while (!program.isStopped())
|
||||||
|
vm.step(program);
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
program.setRuntimeFailure(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("============ Results ============");
|
||||||
|
|
||||||
|
System.out.println("*** Used gas: " + program.getResult().getGasUsed());
|
||||||
|
// TODO: check that the value pushed after exec is the new address
|
||||||
|
repository.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // CALL contract with too much gas
|
||||||
|
@Ignore
|
||||||
|
public void test5() {
|
||||||
|
// TODO CALL contract with gas > gasRemaining && gas > Long.MAX_VALUE
|
||||||
|
}
|
||||||
|
|
||||||
|
@Ignore
|
||||||
|
@Test // contractB call itself with code from contractA
|
||||||
|
public void test6() {
|
||||||
|
/**
|
||||||
|
* #The code will run
|
||||||
|
* ------------------
|
||||||
|
|
||||||
|
contract A: 945304eb96065b2a98b57a48a06ae28d285a71b5
|
||||||
|
---------------
|
||||||
|
|
||||||
|
PUSH1 0 CALLDATALOAD SLOAD NOT PUSH1 9 JUMPI STOP
|
||||||
|
PUSH1 32 CALLDATALOAD PUSH1 0 CALLDATALOAD SSTORE
|
||||||
|
|
||||||
|
contract B: 0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6
|
||||||
|
-----------
|
||||||
|
{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
|
||||||
|
(MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa)
|
||||||
|
[[ 0 ]] (CALLSTATELESS 1000000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 64 64 0)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Set contract into Database
|
||||||
|
byte[] caller_addr_bytes = Hex.decode("cd1722f3947def4cf144679da39c4c32bdc35681");
|
||||||
|
|
||||||
|
byte[] contractA_addr_bytes = Hex.decode("945304eb96065b2a98b57a48a06ae28d285a71b5");
|
||||||
|
byte[] contractB_addr_bytes = Hex.decode("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6");
|
||||||
|
|
||||||
|
byte[] codeA = Hex.decode("60003554156009570060203560003555");
|
||||||
|
byte[] codeB = Hex.decode("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000527faaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa6020526000604060406000601773945304eb96065b2a98b57a48a06ae28d285a71b5620f4240f3600055");
|
||||||
|
|
||||||
|
ProgramInvokeMockImpl pi = new ProgramInvokeMockImpl();
|
||||||
|
pi.setOwnerAddress(contractB_addr_bytes);
|
||||||
|
pi.setGasLimit(10000000000000l);
|
||||||
|
|
||||||
|
Repository repository = pi.getRepository();
|
||||||
|
repository.createAccount(contractA_addr_bytes);
|
||||||
|
repository.saveCode(contractA_addr_bytes, codeA);
|
||||||
|
repository.addBalance(contractA_addr_bytes, BigInteger.valueOf(23));
|
||||||
|
|
||||||
|
repository.createAccount(contractB_addr_bytes);
|
||||||
|
repository.saveCode(contractB_addr_bytes, codeB);
|
||||||
|
repository.addBalance(contractB_addr_bytes, new BigInteger("1000000000000000000"));
|
||||||
|
|
||||||
|
repository.createAccount(caller_addr_bytes);
|
||||||
|
repository.addBalance(caller_addr_bytes, new BigInteger("100000000000000000000"));
|
||||||
|
|
||||||
|
// ****************** //
|
||||||
|
// Play the program //
|
||||||
|
// ****************** //
|
||||||
|
VM vm = new VM();
|
||||||
|
Program program = new Program(codeB, pi);
|
||||||
|
|
||||||
|
try {
|
||||||
|
while (!program.isStopped())
|
||||||
|
vm.step(program);
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
program.setRuntimeFailure(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println();
|
||||||
|
System.out.println("============ Results ============");
|
||||||
|
System.out.println("*** Used gas: " + program.getResult().getGasUsed());
|
||||||
|
|
||||||
|
DataWord memValue1 = program.memoryLoad(new DataWord(0));
|
||||||
|
DataWord memValue2 = program.memoryLoad(new DataWord(32));
|
||||||
|
|
||||||
|
DataWord storeValue1 = repository.getStorageValue(contractB_addr_bytes, new DataWord(00));
|
||||||
|
|
||||||
|
repository.close();
|
||||||
|
|
||||||
|
assertEquals("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", memValue1.toString());
|
||||||
|
assertEquals("aaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa", memValue2.toString());
|
||||||
|
|
||||||
|
assertEquals("0x1", storeValue1.shortHex());
|
||||||
|
|
||||||
|
// TODO: check that the value pushed after exec is 1
|
||||||
|
}
|
||||||
|
|
||||||
|
//sha3_memSizeQuadraticCost33
|
||||||
|
@Ignore //TODO #POC9
|
||||||
|
@Test // contract call quadratic memory use
|
||||||
|
public void test7() {
|
||||||
|
|
||||||
|
int expectedGas = 357;
|
||||||
|
|
||||||
|
DataWord key1 = new DataWord(999);
|
||||||
|
DataWord value1 = new DataWord(3);
|
||||||
|
|
||||||
|
// Set contract into Database
|
||||||
|
String callerAddr = "cd1722f3947def4cf144679da39c4c32bdc35681";
|
||||||
|
String contractAddr = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6";
|
||||||
|
String code = "600161040020600055";
|
||||||
|
|
||||||
|
byte[] contractAddrB = Hex.decode(contractAddr);
|
||||||
|
byte[] callerAddrB = Hex.decode(callerAddr);
|
||||||
|
byte[] codeB = Hex.decode(code);
|
||||||
|
|
||||||
|
byte[] codeKey = HashUtil.sha3(codeB);
|
||||||
|
AccountState accountState = new AccountState();
|
||||||
|
accountState.setCodeHash(codeKey);
|
||||||
|
|
||||||
|
ProgramInvokeMockImpl pi = new ProgramInvokeMockImpl();
|
||||||
|
pi.setOwnerAddress(contractAddrB);
|
||||||
|
Repository repository = pi.getRepository();
|
||||||
|
|
||||||
|
repository.createAccount(callerAddrB);
|
||||||
|
repository.addBalance(callerAddrB, new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639935"));
|
||||||
|
|
||||||
|
repository.createAccount(contractAddrB);
|
||||||
|
repository.saveCode(contractAddrB, codeB);
|
||||||
|
repository.addStorageRow(contractAddrB, key1, value1);
|
||||||
|
|
||||||
|
// Play the program
|
||||||
|
VM vm = new VM();
|
||||||
|
Program program = new Program(codeB, pi);
|
||||||
|
|
||||||
|
try {
|
||||||
|
while (!program.isStopped())
|
||||||
|
vm.step(program);
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
program.setRuntimeFailure(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println();
|
||||||
|
System.out.println("============ Results ============");
|
||||||
|
|
||||||
|
BigInteger balance = repository.getBalance(callerAddrB);
|
||||||
|
|
||||||
|
System.out.println("*** Used gas: " + program.getResult().getGasUsed());
|
||||||
|
System.out.println("*** Contract Balance: " + balance);
|
||||||
|
|
||||||
|
// todo: assert caller balance after contract exec
|
||||||
|
|
||||||
|
repository.close();
|
||||||
|
assertEquals(expectedGas, program.getResult().getGasUsed());
|
||||||
|
}
|
||||||
|
|
||||||
|
//sha3_memSizeQuadraticCost31
|
||||||
|
@Ignore //TODO #POC9
|
||||||
|
@Test // contract call quadratic memory use
|
||||||
|
public void test8() {
|
||||||
|
|
||||||
|
int expectedGas = 354;
|
||||||
|
|
||||||
|
DataWord key1 = new DataWord(999);
|
||||||
|
DataWord value1 = new DataWord(3);
|
||||||
|
|
||||||
|
// Set contract into Database
|
||||||
|
String callerAddr = "cd1722f3947def4cf144679da39c4c32bdc35681";
|
||||||
|
String contractAddr = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6";
|
||||||
|
String code = "60016103c020600055";
|
||||||
|
|
||||||
|
byte[] contractAddrB = Hex.decode(contractAddr);
|
||||||
|
byte[] callerAddrB = Hex.decode(callerAddr);
|
||||||
|
byte[] codeB = Hex.decode(code);
|
||||||
|
|
||||||
|
byte[] codeKey = HashUtil.sha3(codeB);
|
||||||
|
AccountState accountState = new AccountState();
|
||||||
|
accountState.setCodeHash(codeKey);
|
||||||
|
|
||||||
|
ProgramInvokeMockImpl pi = new ProgramInvokeMockImpl();
|
||||||
|
pi.setOwnerAddress(contractAddrB);
|
||||||
|
Repository repository = pi.getRepository();
|
||||||
|
|
||||||
|
repository.createAccount(callerAddrB);
|
||||||
|
repository.addBalance(callerAddrB, new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639935"));
|
||||||
|
|
||||||
|
repository.createAccount(contractAddrB);
|
||||||
|
repository.saveCode(contractAddrB, codeB);
|
||||||
|
repository.addStorageRow(contractAddrB, key1, value1);
|
||||||
|
|
||||||
|
// Play the program
|
||||||
|
VM vm = new VM();
|
||||||
|
Program program = new Program(codeB, pi);
|
||||||
|
|
||||||
|
try {
|
||||||
|
while (!program.isStopped())
|
||||||
|
vm.step(program);
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
program.setRuntimeFailure(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println();
|
||||||
|
System.out.println("============ Results ============");
|
||||||
|
|
||||||
|
BigInteger balance = repository.getBalance(callerAddrB);
|
||||||
|
|
||||||
|
System.out.println("*** Used gas: " + program.getResult().getGasUsed());
|
||||||
|
System.out.println("*** Contract Balance: " + balance);
|
||||||
|
|
||||||
|
// todo: assert caller balance after contract exec
|
||||||
|
|
||||||
|
repository.close();
|
||||||
|
assertEquals(expectedGas, program.getResult().getGasUsed());
|
||||||
|
}
|
||||||
|
|
||||||
|
//sha3_memSizeQuadraticCost32
|
||||||
|
@Ignore //TODO #POC9
|
||||||
|
@Test // contract call quadratic memory use
|
||||||
|
public void test9() {
|
||||||
|
|
||||||
|
int expectedGas = 356;
|
||||||
|
|
||||||
|
DataWord key1 = new DataWord(9999);
|
||||||
|
DataWord value1 = new DataWord(3);
|
||||||
|
|
||||||
|
// Set contract into Database
|
||||||
|
String callerAddr = "cd1722f3947def4cf144679da39c4c32bdc35681";
|
||||||
|
String contractAddr = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6";
|
||||||
|
String code = "60016103e020600055";
|
||||||
|
|
||||||
|
byte[] contractAddrB = Hex.decode(contractAddr);
|
||||||
|
byte[] callerAddrB = Hex.decode(callerAddr);
|
||||||
|
byte[] codeB = Hex.decode(code);
|
||||||
|
|
||||||
|
byte[] codeKey = HashUtil.sha3(codeB);
|
||||||
|
AccountState accountState = new AccountState();
|
||||||
|
accountState.setCodeHash(codeKey);
|
||||||
|
|
||||||
|
ProgramInvokeMockImpl pi = new ProgramInvokeMockImpl();
|
||||||
|
pi.setOwnerAddress(contractAddrB);
|
||||||
|
Repository repository = pi.getRepository();
|
||||||
|
|
||||||
|
repository.createAccount(callerAddrB);
|
||||||
|
repository.addBalance(callerAddrB, new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639935"));
|
||||||
|
|
||||||
|
repository.createAccount(contractAddrB);
|
||||||
|
repository.saveCode(contractAddrB, codeB);
|
||||||
|
repository.addStorageRow(contractAddrB, key1, value1);
|
||||||
|
|
||||||
|
// Play the program
|
||||||
|
VM vm = new VM();
|
||||||
|
Program program = new Program(codeB, pi);
|
||||||
|
|
||||||
|
try {
|
||||||
|
while (!program.isStopped())
|
||||||
|
vm.step(program);
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
program.setRuntimeFailure(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println();
|
||||||
|
System.out.println("============ Results ============");
|
||||||
|
|
||||||
|
BigInteger balance = repository.getBalance(callerAddrB);
|
||||||
|
|
||||||
|
System.out.println("*** Used gas: " + program.getResult().getGasUsed());
|
||||||
|
System.out.println("*** Contract Balance: " + balance);
|
||||||
|
|
||||||
|
// todo: assert caller balance after contract exec
|
||||||
|
|
||||||
|
repository.close();
|
||||||
|
assertEquals(expectedGas, program.getResult().getGasUsed());
|
||||||
|
}
|
||||||
|
|
||||||
|
//sha3_memSizeQuadraticCost32_zeroSize
|
||||||
|
@Ignore //TODO #POC9
|
||||||
|
@Test // contract call quadratic memory use
|
||||||
|
public void test10() {
|
||||||
|
|
||||||
|
int expectedGas = 313;
|
||||||
|
|
||||||
|
DataWord key1 = new DataWord(999);
|
||||||
|
DataWord value1 = new DataWord(3);
|
||||||
|
|
||||||
|
// Set contract into Database
|
||||||
|
String callerAddr = "cd1722f3947def4cf144679da39c4c32bdc35681";
|
||||||
|
String contractAddr = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6";
|
||||||
|
String code = "600061040020600055";
|
||||||
|
|
||||||
|
byte[] contractAddrB = Hex.decode(contractAddr);
|
||||||
|
byte[] callerAddrB = Hex.decode(callerAddr);
|
||||||
|
byte[] codeB = Hex.decode(code);
|
||||||
|
|
||||||
|
byte[] codeKey = HashUtil.sha3(codeB);
|
||||||
|
AccountState accountState = new AccountState();
|
||||||
|
accountState.setCodeHash(codeKey);
|
||||||
|
|
||||||
|
ProgramInvokeMockImpl pi = new ProgramInvokeMockImpl();
|
||||||
|
pi.setOwnerAddress(contractAddrB);
|
||||||
|
Repository repository = pi.getRepository();
|
||||||
|
|
||||||
|
repository.createAccount(callerAddrB);
|
||||||
|
repository.addBalance(callerAddrB, new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639935"));
|
||||||
|
|
||||||
|
repository.createAccount(contractAddrB);
|
||||||
|
repository.saveCode(contractAddrB, codeB);
|
||||||
|
repository.addStorageRow(contractAddrB, key1, value1);
|
||||||
|
|
||||||
|
// Play the program
|
||||||
|
VM vm = new VM();
|
||||||
|
Program program = new Program(codeB, pi);
|
||||||
|
|
||||||
|
try {
|
||||||
|
while (!program.isStopped())
|
||||||
|
vm.step(program);
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
program.setRuntimeFailure(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println();
|
||||||
|
System.out.println("============ Results ============");
|
||||||
|
|
||||||
|
BigInteger balance = repository.getBalance(callerAddrB);
|
||||||
|
|
||||||
|
System.out.println("*** Used gas: " + program.getResult().getGasUsed());
|
||||||
|
System.out.println("*** Contract Balance: " + balance);
|
||||||
|
|
||||||
|
// todo: assert caller balance after contract exec
|
||||||
|
|
||||||
|
repository.close();
|
||||||
|
assertEquals(expectedGas, program.getResult().getGasUsed());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,564 @@
|
||||||
|
package org.ethereum.vm;
|
||||||
|
|
||||||
|
import org.ethereum.vm.Program.OutOfGasException;
|
||||||
|
import org.ethereum.vm.Program.StackTooSmallException;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.FixMethodOrder;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runners.MethodSorters;
|
||||||
|
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Roman Mandeleil
|
||||||
|
* @since 01.06.2014
|
||||||
|
*/
|
||||||
|
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||||
|
public class VMCustomTest {
|
||||||
|
|
||||||
|
private ProgramInvokeMockImpl invoke;
|
||||||
|
private Program program;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() {
|
||||||
|
byte[] ownerAddress = Hex.decode("77045E71A7A2C50903D88E564CD72FAB11E82051");
|
||||||
|
byte[] msgData = Hex.decode("00000000000000000000000000000000000000000000000000000000000000A1" +
|
||||||
|
"00000000000000000000000000000000000000000000000000000000000000B1");
|
||||||
|
|
||||||
|
invoke = new ProgramInvokeMockImpl(msgData);
|
||||||
|
invoke.setOwnerAddress(ownerAddress);
|
||||||
|
|
||||||
|
invoke.getRepository().createAccount(ownerAddress);
|
||||||
|
invoke.getRepository().addBalance(ownerAddress, BigInteger.valueOf(1000L));
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
invoke.getRepository().close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // CALLDATASIZE OP
|
||||||
|
public void testCALLDATASIZE_1() {
|
||||||
|
|
||||||
|
VM vm = new VM();
|
||||||
|
program = new Program(Hex.decode("36"), invoke);
|
||||||
|
String s_expected_1 = "0000000000000000000000000000000000000000000000000000000000000040";
|
||||||
|
|
||||||
|
vm.step(program);
|
||||||
|
|
||||||
|
DataWord item1 = program.stackPop();
|
||||||
|
assertEquals(s_expected_1, Hex.toHexString(item1.getData()).toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test // CALLDATALOAD OP
|
||||||
|
public void testCALLDATALOAD_1() {
|
||||||
|
|
||||||
|
VM vm = new VM();
|
||||||
|
program =
|
||||||
|
new Program(Hex.decode("600035"), invoke);
|
||||||
|
String s_expected_1 = "00000000000000000000000000000000000000000000000000000000000000A1";
|
||||||
|
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
|
||||||
|
DataWord item1 = program.stackPop();
|
||||||
|
assertEquals(s_expected_1, Hex.toHexString(item1.getData()).toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // CALLDATALOAD OP
|
||||||
|
public void testCALLDATALOAD_2() {
|
||||||
|
|
||||||
|
VM vm = new VM();
|
||||||
|
program =
|
||||||
|
new Program(Hex.decode("600235"), invoke);
|
||||||
|
String s_expected_1 = "0000000000000000000000000000000000000000000000000000000000A10000";
|
||||||
|
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
|
||||||
|
DataWord item1 = program.stackPop();
|
||||||
|
assertEquals(s_expected_1, Hex.toHexString(item1.getData()).toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test // CALLDATALOAD OP
|
||||||
|
public void testCALLDATALOAD_3() {
|
||||||
|
|
||||||
|
VM vm = new VM();
|
||||||
|
program =
|
||||||
|
new Program(Hex.decode("602035"), invoke);
|
||||||
|
String s_expected_1 = "00000000000000000000000000000000000000000000000000000000000000B1";
|
||||||
|
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
|
||||||
|
DataWord item1 = program.stackPop();
|
||||||
|
assertEquals(s_expected_1, Hex.toHexString(item1.getData()).toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test // CALLDATALOAD OP
|
||||||
|
public void testCALLDATALOAD_4() {
|
||||||
|
|
||||||
|
VM vm = new VM();
|
||||||
|
program =
|
||||||
|
new Program(Hex.decode("602335"), invoke);
|
||||||
|
String s_expected_1 = "00000000000000000000000000000000000000000000000000000000B1000000";
|
||||||
|
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
|
||||||
|
DataWord item1 = program.stackPop();
|
||||||
|
assertEquals(s_expected_1, Hex.toHexString(item1.getData()).toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // CALLDATALOAD OP
|
||||||
|
public void testCALLDATALOAD_5() {
|
||||||
|
|
||||||
|
VM vm = new VM();
|
||||||
|
program =
|
||||||
|
new Program(Hex.decode("603F35"), invoke);
|
||||||
|
String s_expected_1 = "B100000000000000000000000000000000000000000000000000000000000000";
|
||||||
|
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
|
||||||
|
DataWord item1 = program.stackPop();
|
||||||
|
assertEquals(s_expected_1, Hex.toHexString(item1.getData()).toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = RuntimeException.class) // CALLDATALOAD OP mal
|
||||||
|
public void testCALLDATALOAD_6() {
|
||||||
|
|
||||||
|
VM vm = new VM();
|
||||||
|
program =
|
||||||
|
new Program(Hex.decode("35"), invoke);
|
||||||
|
try {
|
||||||
|
vm.step(program);
|
||||||
|
} finally {
|
||||||
|
assertTrue(program.isStopped());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // CALLDATACOPY OP
|
||||||
|
public void testCALLDATACOPY_1() {
|
||||||
|
|
||||||
|
VM vm = new VM();
|
||||||
|
program =
|
||||||
|
new Program(Hex.decode("60206000600037"), invoke);
|
||||||
|
String m_expected = "00000000000000000000000000000000000000000000000000000000000000A1";
|
||||||
|
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
|
||||||
|
assertEquals(m_expected, Hex.toHexString(program.getMemory()).toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // CALLDATACOPY OP
|
||||||
|
public void testCALLDATACOPY_2() {
|
||||||
|
|
||||||
|
VM vm = new VM();
|
||||||
|
program =
|
||||||
|
new Program(Hex.decode("60406000600037"), invoke);
|
||||||
|
String m_expected = "00000000000000000000000000000000000000000000000000000000000000A1" +
|
||||||
|
"00000000000000000000000000000000000000000000000000000000000000B1";
|
||||||
|
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
|
||||||
|
assertEquals(m_expected, Hex.toHexString(program.getMemory()).toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test // CALLDATACOPY OP
|
||||||
|
public void testCALLDATACOPY_3() {
|
||||||
|
|
||||||
|
VM vm = new VM();
|
||||||
|
program =
|
||||||
|
new Program(Hex.decode("60406004600037"), invoke);
|
||||||
|
String m_expected = "000000000000000000000000000000000000000000000000000000A100000000" +
|
||||||
|
"000000000000000000000000000000000000000000000000000000B100000000";
|
||||||
|
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
|
||||||
|
assertEquals(m_expected, Hex.toHexString(program.getMemory()).toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test // CALLDATACOPY OP
|
||||||
|
public void testCALLDATACOPY_4() {
|
||||||
|
|
||||||
|
VM vm = new VM();
|
||||||
|
program =
|
||||||
|
new Program(Hex.decode("60406000600437"), invoke);
|
||||||
|
String m_expected = "0000000000000000000000000000000000000000000000000000000000000000" +
|
||||||
|
"000000A100000000000000000000000000000000000000000000000000000000" +
|
||||||
|
"000000B100000000000000000000000000000000000000000000000000000000";
|
||||||
|
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
|
||||||
|
assertEquals(m_expected, Hex.toHexString(program.getMemory()).toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // CALLDATACOPY OP
|
||||||
|
public void testCALLDATACOPY_5() {
|
||||||
|
|
||||||
|
VM vm = new VM();
|
||||||
|
program =
|
||||||
|
new Program(Hex.decode("60406000600437"), invoke);
|
||||||
|
String m_expected = "0000000000000000000000000000000000000000000000000000000000000000" +
|
||||||
|
"000000A100000000000000000000000000000000000000000000000000000000" +
|
||||||
|
"000000B100000000000000000000000000000000000000000000000000000000";
|
||||||
|
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
|
||||||
|
assertEquals(m_expected, Hex.toHexString(program.getMemory()).toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test(expected = StackTooSmallException.class) // CALLDATACOPY OP mal
|
||||||
|
public void testCALLDATACOPY_6() {
|
||||||
|
|
||||||
|
VM vm = new VM();
|
||||||
|
program =
|
||||||
|
new Program(Hex.decode("6040600037"), invoke);
|
||||||
|
|
||||||
|
try {
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
} finally {
|
||||||
|
assertTrue(program.isStopped());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = OutOfGasException.class) // CALLDATACOPY OP mal
|
||||||
|
public void testCALLDATACOPY_7() {
|
||||||
|
|
||||||
|
VM vm = new VM();
|
||||||
|
program =
|
||||||
|
new Program(Hex.decode("6020600073CC0929EB16730E7C14FEFC63006AC2D794C5795637"), invoke);
|
||||||
|
|
||||||
|
try {
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
} finally {
|
||||||
|
assertTrue(program.isStopped());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // ADDRESS OP
|
||||||
|
public void testADDRESS_1() {
|
||||||
|
|
||||||
|
VM vm = new VM();
|
||||||
|
program = new Program(Hex.decode("30"), invoke);
|
||||||
|
String s_expected_1 = "00000000000000000000000077045E71A7A2C50903D88E564CD72FAB11E82051";
|
||||||
|
|
||||||
|
vm.step(program);
|
||||||
|
|
||||||
|
DataWord item1 = program.stackPop();
|
||||||
|
program.getResult().getRepository().close();
|
||||||
|
assertEquals(s_expected_1, Hex.toHexString(item1.getData()).toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // BALANCE OP
|
||||||
|
public void testBALANCE_1() {
|
||||||
|
|
||||||
|
VM vm = new VM();
|
||||||
|
program =
|
||||||
|
new Program(Hex.decode("3031"), invoke);
|
||||||
|
String s_expected_1 = "00000000000000000000000000000000000000000000000000000000000003E8";
|
||||||
|
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
|
||||||
|
DataWord item1 = program.stackPop();
|
||||||
|
assertEquals(s_expected_1, Hex.toHexString(item1.getData()).toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // ORIGIN OP
|
||||||
|
public void testORIGIN_1() {
|
||||||
|
|
||||||
|
VM vm = new VM();
|
||||||
|
program =
|
||||||
|
new Program(Hex.decode("32"), invoke);
|
||||||
|
String s_expected_1 = "00000000000000000000000013978AEE95F38490E9769C39B2773ED763D9CD5F";
|
||||||
|
|
||||||
|
vm.step(program);
|
||||||
|
|
||||||
|
DataWord item1 = program.stackPop();
|
||||||
|
assertEquals(s_expected_1, Hex.toHexString(item1.getData()).toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // CALLER OP
|
||||||
|
public void testCALLER_1() {
|
||||||
|
|
||||||
|
VM vm = new VM();
|
||||||
|
program =
|
||||||
|
new Program(Hex.decode("33"), invoke);
|
||||||
|
String s_expected_1 = "000000000000000000000000885F93EED577F2FC341EBB9A5C9B2CE4465D96C4";
|
||||||
|
|
||||||
|
vm.step(program);
|
||||||
|
|
||||||
|
DataWord item1 = program.stackPop();
|
||||||
|
assertEquals(s_expected_1, Hex.toHexString(item1.getData()).toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // CALLVALUE OP
|
||||||
|
public void testCALLVALUE_1() {
|
||||||
|
|
||||||
|
VM vm = new VM();
|
||||||
|
program =
|
||||||
|
new Program(Hex.decode("34"), invoke);
|
||||||
|
String s_expected_1 = "0000000000000000000000000000000000000000000000000DE0B6B3A7640000";
|
||||||
|
|
||||||
|
vm.step(program);
|
||||||
|
|
||||||
|
DataWord item1 = program.stackPop();
|
||||||
|
assertEquals(s_expected_1, Hex.toHexString(item1.getData()).toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // SHA3 OP
|
||||||
|
public void testSHA3_1() {
|
||||||
|
|
||||||
|
VM vm = new VM();
|
||||||
|
program =
|
||||||
|
new Program(Hex.decode("60016000536001600020"), invoke);
|
||||||
|
String s_expected_1 = "5FE7F977E71DBA2EA1A68E21057BEEBB9BE2AC30C6410AA38D4F3FBE41DCFFD2";
|
||||||
|
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
|
||||||
|
DataWord item1 = program.stackPop();
|
||||||
|
assertEquals(s_expected_1, Hex.toHexString(item1.getData()).toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // SHA3 OP
|
||||||
|
public void testSHA3_2() {
|
||||||
|
|
||||||
|
VM vm = new VM();
|
||||||
|
program =
|
||||||
|
new Program(Hex.decode("6102016000526002601E20"), invoke);
|
||||||
|
String s_expected_1 = "114A3FE82A0219FCC31ABD15617966A125F12B0FD3409105FC83B487A9D82DE4";
|
||||||
|
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
|
||||||
|
DataWord item1 = program.stackPop();
|
||||||
|
assertEquals(s_expected_1, Hex.toHexString(item1.getData()).toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = StackTooSmallException.class) // SHA3 OP mal
|
||||||
|
public void testSHA3_3() {
|
||||||
|
|
||||||
|
VM vm = new VM();
|
||||||
|
program =
|
||||||
|
new Program(Hex.decode("610201600052600220"), invoke);
|
||||||
|
try {
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
} finally {
|
||||||
|
assertTrue(program.isStopped());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // BLOCKHASH OP
|
||||||
|
public void testBLOCKHASH_1() {
|
||||||
|
|
||||||
|
VM vm = new VM();
|
||||||
|
program =
|
||||||
|
new Program(Hex.decode("600140"), invoke);
|
||||||
|
String s_expected_1 = "C89EFDAA54C0F20C7ADF612882DF0950F5A951637E0307CDCB4C672F298B8BC6";
|
||||||
|
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
|
||||||
|
DataWord item1 = program.stackPop();
|
||||||
|
assertEquals(s_expected_1, Hex.toHexString(item1.getData()).toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // COINBASE OP
|
||||||
|
public void testCOINBASE_1() {
|
||||||
|
|
||||||
|
VM vm = new VM();
|
||||||
|
program =
|
||||||
|
new Program(Hex.decode("41"), invoke);
|
||||||
|
String s_expected_1 = "000000000000000000000000E559DE5527492BCB42EC68D07DF0742A98EC3F1E";
|
||||||
|
|
||||||
|
vm.step(program);
|
||||||
|
|
||||||
|
DataWord item1 = program.stackPop();
|
||||||
|
assertEquals(s_expected_1, Hex.toHexString(item1.getData()).toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // TIMESTAMP OP
|
||||||
|
public void testTIMESTAMP_1() {
|
||||||
|
|
||||||
|
VM vm = new VM();
|
||||||
|
program =
|
||||||
|
new Program(Hex.decode("42"), invoke);
|
||||||
|
String s_expected_1 = "000000000000000000000000000000000000000000000000000000005387FE24";
|
||||||
|
|
||||||
|
vm.step(program);
|
||||||
|
|
||||||
|
DataWord item1 = program.stackPop();
|
||||||
|
assertEquals(s_expected_1, Hex.toHexString(item1.getData()).toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // NUMBER OP
|
||||||
|
public void testNUMBER_1() {
|
||||||
|
|
||||||
|
VM vm = new VM();
|
||||||
|
program =
|
||||||
|
new Program(Hex.decode("43"), invoke);
|
||||||
|
String s_expected_1 = "0000000000000000000000000000000000000000000000000000000000000021";
|
||||||
|
|
||||||
|
vm.step(program);
|
||||||
|
|
||||||
|
DataWord item1 = program.stackPop();
|
||||||
|
assertEquals(s_expected_1, Hex.toHexString(item1.getData()).toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // DIFFICULTY OP
|
||||||
|
public void testDIFFICULTY_1() {
|
||||||
|
|
||||||
|
VM vm = new VM();
|
||||||
|
program =
|
||||||
|
new Program(Hex.decode("44"), invoke);
|
||||||
|
String s_expected_1 = "00000000000000000000000000000000000000000000000000000000003ED290";
|
||||||
|
|
||||||
|
vm.step(program);
|
||||||
|
|
||||||
|
DataWord item1 = program.stackPop();
|
||||||
|
assertEquals(s_expected_1, Hex.toHexString(item1.getData()).toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // GASPRICE OP
|
||||||
|
public void testGASPRICE_1() {
|
||||||
|
|
||||||
|
VM vm = new VM();
|
||||||
|
program =
|
||||||
|
new Program(Hex.decode("3A"), invoke);
|
||||||
|
String s_expected_1 = "000000000000000000000000000000000000000000000000000009184E72A000";
|
||||||
|
|
||||||
|
vm.step(program);
|
||||||
|
|
||||||
|
DataWord item1 = program.stackPop();
|
||||||
|
assertEquals(s_expected_1, Hex.toHexString(item1.getData()).toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Ignore //TODO #POC9
|
||||||
|
@Test // GAS OP
|
||||||
|
public void testGAS_1() {
|
||||||
|
|
||||||
|
VM vm = new VM();
|
||||||
|
program =
|
||||||
|
new Program(Hex.decode("5A"), invoke);
|
||||||
|
String s_expected_1 = "00000000000000000000000000000000000000000000000000000000000F423F";
|
||||||
|
|
||||||
|
vm.step(program);
|
||||||
|
|
||||||
|
DataWord item1 = program.stackPop();
|
||||||
|
assertEquals(s_expected_1, Hex.toHexString(item1.getData()).toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // GASLIMIT OP
|
||||||
|
public void testGASLIMIT_1() {
|
||||||
|
|
||||||
|
VM vm = new VM();
|
||||||
|
program =
|
||||||
|
new Program(Hex.decode("45"), invoke);
|
||||||
|
String s_expected_1 = "00000000000000000000000000000000000000000000000000000000000F4240";
|
||||||
|
|
||||||
|
vm.step(program);
|
||||||
|
|
||||||
|
DataWord item1 = program.stackPop();
|
||||||
|
assertEquals(s_expected_1, Hex.toHexString(item1.getData()).toUpperCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = Program.IllegalOperationException.class) // INVALID OP
|
||||||
|
public void testINVALID_1() {
|
||||||
|
|
||||||
|
VM vm = new VM();
|
||||||
|
program = new Program(Hex.decode("60012F6002"), invoke);
|
||||||
|
String s_expected_1 = "0000000000000000000000000000000000000000000000000000000000000001";
|
||||||
|
|
||||||
|
try {
|
||||||
|
vm.step(program);
|
||||||
|
vm.step(program);
|
||||||
|
} finally {
|
||||||
|
assertTrue(program.isStopped());
|
||||||
|
DataWord item1 = program.stackPop();
|
||||||
|
assertEquals(s_expected_1, Hex.toHexString(item1.getData()).toUpperCase());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TEST CASE LIST END */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: add gas expeted and calculated to all test cases
|
||||||
|
// TODO: considering: G_TXDATA + G_TRANSACTION
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO:
|
||||||
|
*
|
||||||
|
* 22) CREATE:
|
||||||
|
* 23) CALL:
|
||||||
|
*
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
contract creation (gas usage)
|
||||||
|
-----------------------------
|
||||||
|
G_TRANSACTION = (500)
|
||||||
|
60016000546006601160003960066000f261778e600054 (115)
|
||||||
|
PUSH1 6001 (1)
|
||||||
|
PUSH1 6000 (1)
|
||||||
|
MSTORE 54 (1 + 1)
|
||||||
|
PUSH1 6006 (1)
|
||||||
|
PUSH1 6011 (1)
|
||||||
|
PUSH1 6000 (1)
|
||||||
|
CODECOPY 39 (1)
|
||||||
|
PUSH1 6006 (1)
|
||||||
|
PUSH1 6000 (1)
|
||||||
|
RETURN f2 (1)
|
||||||
|
61778e600054
|
||||||
|
|
||||||
|
*/
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue