diff --git a/ethereumj-core/src/main/java/org/ethereum/core/Block.java b/ethereumj-core/src/main/java/org/ethereum/core/Block.java index 53b40fe2..36225842 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/Block.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/Block.java @@ -71,7 +71,11 @@ public class Block { difficulty, number, minGasPrice, gasLimit, gasUsed, timestamp, extraData, nonce); this.txsState = new Trie(null); - this.header.setStateRoot(WorldManager.instance.worldState.getRootHash()); + + // TODO: REFACTOR REPOSITORY TO GET ROOT HASH FOR HERE + // TODO: REFACTOR REPOSITORY TO GET ROOT HASH FOR HERE + // TODO: REFACTOR REPOSITORY TO GET ROOT HASH FOR HERE + this.header.setStateRoot(null); this.header.setTxTrieRoot(txsState.getRootHash()); this.transactionsList = transactionsList; this.uncleList = uncleList; @@ -197,7 +201,7 @@ public class Block { public List getTransactionsList() { if (!parsed) parseRLP(); if (transactionsList == null) { - this.transactionsList = new ArrayList(); + this.transactionsList = new ArrayList<>(); } return transactionsList; } @@ -205,7 +209,7 @@ public class Block { public List getTxReceiptList() { if (!parsed) parseRLP(); if (transactionsList == null) { - this.txReceiptList = new ArrayList(); + this.txReceiptList = new ArrayList<>(); } return txReceiptList; } @@ -213,7 +217,7 @@ public class Block { public List getUncleList() { if (!parsed) parseRLP(); if (uncleList == null) { - this.uncleList = new ArrayList(); + this.uncleList = new ArrayList<>(); } return uncleList; } @@ -299,14 +303,6 @@ public class Block { // this.allAccountsState.update(); } - public byte[] updateState(byte[] key, byte[] value) { - - WorldManager.instance.worldState.update(key, value); - byte[] stateRoot = WorldManager.instance.worldState.getRootHash(); - this.header.setStateRoot(stateRoot); - return stateRoot; - } - /** * This mechanism enforces a homeostasis in terms of the time between blocks; * a smaller period between the last two blocks results in an increase in the @@ -320,7 +316,6 @@ public class Block { if(!this.isGenesis()) { // verify difficulty meets requirements isValid = this.getDifficulty() == this.calcDifficulty(); - // verify nonce meest difficulty requirements isValid = this.validateNonce(); // verify gasLimit meets requirements isValid = this.getGasLimit() == this.calcGasLimit(); @@ -367,9 +362,6 @@ public class Block { /** * Verify that block is valid for its difficulty * - * @param block - * @param difficulty - * @param testNonce * @return */ public boolean validateNonce() { diff --git a/ethereumj-core/src/main/java/org/ethereum/core/ContractDetails.java b/ethereumj-core/src/main/java/org/ethereum/core/ContractDetails.java deleted file mode 100644 index 3aee5995..00000000 --- a/ethereumj-core/src/main/java/org/ethereum/core/ContractDetails.java +++ /dev/null @@ -1,106 +0,0 @@ -package org.ethereum.core; - -import org.ethereum.util.RLP; -import org.ethereum.util.RLPElement; -import org.ethereum.util.RLPItem; -import org.ethereum.util.RLPList; -import org.ethereum.vm.DataWord; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * www.ethereumJ.com - * - * @author: Roman Mandeleil - * Created on: 09/06/2014 15:31 - */ - -public class ContractDetails { - - private byte[] rlpEncoded; - - List storageKeys; - List storageValues; - - public ContractDetails(byte[] rlpEncoded) { - - RLPList data = RLP.decode2(rlpEncoded); - RLPList rlpList = (RLPList)data.get(0); - - RLPList keys = (RLPList)rlpList.get(0); - RLPList values = (RLPList)rlpList.get(1); - - if (keys.size() > 0){ - storageKeys = new ArrayList<>(); - storageValues = new ArrayList<>(); - } - - for (int i = 0; i < keys.size(); ++i){ - - RLPItem rlpItem = (RLPItem)keys.get(i); - storageKeys.add(new DataWord(rlpItem.getRLPData())); - } - - for (int i = 0; i < values.size(); ++i){ - RLPItem rlpItem = (RLPItem)values.get(i); - storageValues.add(new DataWord(rlpItem.getRLPData())); - } - } - - public ContractDetails(Map storage) { - - storageKeys = new ArrayList(); - storageValues = new ArrayList(); - - for(DataWord key : storage.keySet()){ - - DataWord value = storage.get(key); - - storageKeys.add(key); - storageValues.add(value); - } - } - - public byte[] getEncoded() { - if(rlpEncoded == null) { - - byte[][] keys = new byte[storageKeys.size()][]; - byte[][] values = new byte[storageValues.size()][]; - - int i = 0; - for (DataWord key : storageKeys){ - keys[i] = RLP.encodeElement( key.getData()); - ++i; - } - - i = 0; - for (DataWord value : storageValues){ - values[i] = RLP.encodeElement( value.getData() ); - ++i; - } - - byte[] rlpKeysList = RLP.encodeList(keys); - byte[] rlpValuesList = RLP.encodeList(values); - - this.rlpEncoded = RLP.encodeList(rlpKeysList, rlpValuesList); - } - return rlpEncoded; - } - - - public Map getStorage(){ - - Map storage = new HashMap<>(); - - for (int i = 0; - storageKeys != null && - i < storageKeys.size(); ++i){ - storage.put(storageKeys.get(i), storageValues.get(i)); - } - - return storage; - } -} diff --git a/ethereumj-core/src/main/java/org/ethereum/core/Genesis.java b/ethereumj-core/src/main/java/org/ethereum/core/Genesis.java index 4ebef084..4794aeca 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/Genesis.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/Genesis.java @@ -3,6 +3,7 @@ package org.ethereum.core; import java.math.BigInteger; import org.ethereum.crypto.HashUtil; +import org.ethereum.manager.WorldManager; import org.ethereum.util.RLP; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -69,8 +70,9 @@ public class Genesis extends Block { // Premine state for (String address : premine) { - this.updateState(Hex.decode(address), acct.getEncoded()); - } + WorldManager.instance.repository.createAccount(Hex.decode(address)); + WorldManager.instance.repository.addBalance(Hex.decode(address), BigInteger.valueOf(2).pow(200) ); + } logger.info("Genesis-hash: " + Hex.toHexString(this.getHash())); logger.info("Genesis-stateRoot: " + Hex.toHexString(this.getStateRoot())); } diff --git a/ethereumj-core/src/main/java/org/ethereum/db/NewContractDetails.java b/ethereumj-core/src/main/java/org/ethereum/db/ContractDetails.java similarity index 88% rename from ethereumj-core/src/main/java/org/ethereum/db/NewContractDetails.java rename to ethereumj-core/src/main/java/org/ethereum/db/ContractDetails.java index a33f23e6..55418ef4 100644 --- a/ethereumj-core/src/main/java/org/ethereum/db/NewContractDetails.java +++ b/ethereumj-core/src/main/java/org/ethereum/db/ContractDetails.java @@ -17,7 +17,7 @@ import java.util.*; * Created on: 24/06/2014 00:12 */ -public class NewContractDetails { +public class ContractDetails { private byte[] rlpEncoded; @@ -29,18 +29,27 @@ public class NewContractDetails { Trie storageTrie = new Trie(null); - public NewContractDetails(){} - public NewContractDetails(byte[] rlpCode) { + public ContractDetails(){} + public ContractDetails(byte[] rlpCode) { decode(rlpCode); } - public NewContractDetails(Map storage, byte[] code) {} + public ContractDetails(Map storage, byte[] code) {} public void put(DataWord key, DataWord value){ storageTrie.update(key.getData(), value.getData()); + + int index = storageKeys.indexOf(key); + + if (index != -1){ + storageKeys.remove(index); + storageValues.remove(index); + } + storageKeys.add(key); storageValues.add(value); + this.rlpEncoded = null; } @@ -145,7 +154,7 @@ public class NewContractDetails { public Map getStorage(){ - Map storage = Collections.unmodifiableMap(new HashMap()); + Map storage = new HashMap(); for (int i = 0; storageKeys != null && @@ -153,7 +162,7 @@ public class NewContractDetails { storage.put(storageKeys.get(i), storageValues.get(i)); } - return storage; + return Collections.unmodifiableMap(storage); } } diff --git a/ethereumj-core/src/main/java/org/ethereum/db/Repository.java b/ethereumj-core/src/main/java/org/ethereum/db/Repository.java index 60e41099..28c6102b 100644 --- a/ethereumj-core/src/main/java/org/ethereum/db/Repository.java +++ b/ethereumj-core/src/main/java/org/ethereum/db/Repository.java @@ -1,7 +1,6 @@ package org.ethereum.db; import org.ethereum.core.AccountState; -import org.ethereum.core.ContractDetails; import org.ethereum.crypto.HashUtil; import org.ethereum.trie.TrackTrie; import org.ethereum.trie.Trie; @@ -98,7 +97,7 @@ public class Repository { accountStateDB.update(addr, state.getEncoded()); // 2. Save ContractDetails - NewContractDetails details = new NewContractDetails(); + ContractDetails details = new ContractDetails(); contractDetailsDB.put(addr, details.getEncoded()); return state; @@ -119,7 +118,7 @@ public class Repository { return state; } - public NewContractDetails getContractDetails(byte[] addr){ + public ContractDetails getContractDetails(byte[] addr){ byte[] accountDetailsRLP = contractDetailsDB.get(addr); @@ -130,7 +129,7 @@ public class Repository { return null; } - NewContractDetails details = new NewContractDetails(accountDetailsRLP); + ContractDetails details = new ContractDetails(accountDetailsRLP); return details; } @@ -186,7 +185,7 @@ public class Repository { if (address == null || key == null) return; AccountState state = getAccountState(address); - NewContractDetails details = getContractDetails(address); + ContractDetails details = getContractDetails(address); if (state == null || details == null) return; details.put(key, value); @@ -211,7 +210,7 @@ public class Repository { AccountState state = getAccountState(address); if (state == null) return null; - NewContractDetails details = getContractDetails(address); + ContractDetails details = getContractDetails(address); DataWord value = details.get(key); return value; @@ -219,7 +218,7 @@ public class Repository { public byte[] getCode(byte[] address){ - NewContractDetails details = getContractDetails(address); + ContractDetails details = getContractDetails(address); if (details == null) return null; return details.getCode(); @@ -232,7 +231,7 @@ public class Repository { AccountState state = getAccountState(address); if (state == null) return; - NewContractDetails details = getContractDetails(address); + ContractDetails details = getContractDetails(address); details.setCode(code); byte[] codeHash = HashUtil.sha3(code); diff --git a/ethereumj-core/src/main/java/org/ethereum/gui/ContractCallDialog.java b/ethereumj-core/src/main/java/org/ethereum/gui/ContractCallDialog.java index a3d6b079..f8263bac 100644 --- a/ethereumj-core/src/main/java/org/ethereum/gui/ContractCallDialog.java +++ b/ethereumj-core/src/main/java/org/ethereum/gui/ContractCallDialog.java @@ -1,15 +1,13 @@ package org.ethereum.gui; import org.ethereum.core.Account; -import org.ethereum.core.AccountState; -import org.ethereum.core.ContractDetails; import org.ethereum.core.Transaction; +import org.ethereum.db.ContractDetails; import org.ethereum.manager.MainData; import org.ethereum.manager.WorldManager; import org.ethereum.net.client.ClientPeer; import org.ethereum.util.ByteUtil; import org.ethereum.util.Utils; -import org.ethereum.vm.DataWord; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.spongycastle.util.BigIntegers; @@ -27,7 +25,6 @@ import java.awt.event.*; import java.math.BigInteger; import java.net.URL; import java.util.Collection; -import java.util.HashMap; import java.util.Map; import java.util.regex.Pattern; @@ -229,35 +226,8 @@ class ContractCallDialog extends JDialog implements MessageAwareDialog{ } byte[] contractAddress = Hex.decode( contractAddr ); - byte[] contractStateB = WorldManager.instance.worldState.get(contractAddress); - if (contractStateB == null || contractStateB.length == 0){ - return; - } - - AccountState contractState = new AccountState(contractStateB); - final byte[] programCode = WorldManager.instance.chainDB.get(contractState.getCodeHash()); - if (programCode == null || programCode.length == 0){ - return; - } - - byte[] contractDetailsB = - WorldManager.instance.detaildDB.get(contractAddress); - - ContractDetails contractDetails = null; - final Map storageMap = new HashMap(); - - if (contractDetailsB != null){ - - contractDetails = new ContractDetails(contractDetailsB); - Map tmpStorage = contractDetails.getStorage(); - if (tmpStorage != null){ - for (DataWord key : tmpStorage.keySet()){ - String keyToSave = Hex.toHexString (key.getNoLeadZeroesData()); - String valueToSave = Hex.toHexString (tmpStorage.get(key).getNoLeadZeroesData()); - storageMap.put(keyToSave, valueToSave); - } - } - } + final byte[] programCode = WorldManager.instance.repository.getCode(contractAddress); + final Map storageMap = WorldManager.instance.repository.getContractDetails(contractAddress).getStorage(); contractDataInput.setBounds(70, 80, 350, 145); contractDataInput.setViewportView(msgDataTA); @@ -335,31 +305,23 @@ class ContractCallDialog extends JDialog implements MessageAwareDialog{ private void playContractCall() { - byte[] contractAddress = Hex.decode( contractAddrInput.getText()); - byte[] contractStateB = WorldManager.instance.worldState.get(contractAddress); - if (contractStateB == null || contractStateB.length == 0){ + byte[] contractAddress = Hex.decode(contractAddrInput.getText()); + ContractDetails contractDetails = WorldManager.instance.repository.getContractDetails(contractAddress); + if (contractDetails == null){ alertStatusMsg("No contract for that address"); return; } - AccountState contractState = new AccountState(contractStateB); - byte[] programCode = WorldManager.instance.chainDB.get(contractState.getCodeHash()); + byte[] programCode = WorldManager.instance.repository.getCode(contractAddress); if (programCode == null || programCode.length == 0){ alertStatusMsg("Such account exist but no code in the db"); return; } - byte[] contractDetailsB = - WorldManager.instance.detaildDB.get(contractAddress); - - ContractDetails contractDetails = null; - if (contractDetailsB != null && contractDetailsB.length > 0) - contractDetails = new ContractDetails(contractDetailsB); - Transaction tx = createTransaction(); if (tx == null) return; - ProgramPlayDialog.createAndShowGUI(programCode, tx, WorldManager.instance.getBlockChain().getLastBlock(), contractDetails); + ProgramPlayDialog.createAndShowGUI(programCode, tx, WorldManager.instance.getBlockChain().getLastBlock()); } protected JRootPane createRootPane() { diff --git a/ethereumj-core/src/main/java/org/ethereum/gui/ContractSubmitDialog.java b/ethereumj-core/src/main/java/org/ethereum/gui/ContractSubmitDialog.java index 28f80f36..765e50af 100644 --- a/ethereumj-core/src/main/java/org/ethereum/gui/ContractSubmitDialog.java +++ b/ethereumj-core/src/main/java/org/ethereum/gui/ContractSubmitDialog.java @@ -109,7 +109,7 @@ class ContractSubmitDialog extends JDialog implements MessageAwareDialog { contractAddrInput.setText(Hex.toHexString(tx.getContractAddress())); ProgramPlayDialog.createAndShowGUI(tx.getData(), tx, - WorldManager.instance.getBlockChain().getLastBlock(), null); + WorldManager.instance.getBlockChain().getLastBlock()); }} ); diff --git a/ethereumj-core/src/main/java/org/ethereum/gui/ProgramPlayDialog.java b/ethereumj-core/src/main/java/org/ethereum/gui/ProgramPlayDialog.java index c31c770a..33489aed 100644 --- a/ethereumj-core/src/main/java/org/ethereum/gui/ProgramPlayDialog.java +++ b/ethereumj-core/src/main/java/org/ethereum/gui/ProgramPlayDialog.java @@ -1,14 +1,11 @@ package org.ethereum.gui; import org.ethereum.core.Block; -import org.ethereum.core.ContractDetails; import org.ethereum.core.Transaction; -import org.ethereum.db.TrackDatabase; +import org.ethereum.db.Repository; import org.ethereum.manager.WorldManager; import org.ethereum.serpent.SerpentCompiler; -import org.ethereum.trie.TrackTrie; import org.ethereum.vm.*; -import org.spongycastle.util.encoders.Hex; import javax.swing.*; import javax.swing.event.ChangeEvent; @@ -16,7 +13,7 @@ import javax.swing.event.ChangeListener; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.util.*; +import java.util.ArrayList; import java.util.List; /** @@ -52,29 +49,23 @@ public class ProgramPlayDialog extends JPanel implements ActionListener, } - public ProgramPlayDialog(byte[] code, Transaction tx, Block lastBlock, ContractDetails contractDetails) { + public ProgramPlayDialog(byte[] code, Transaction tx, Block lastBlock) { this.tx = tx; outputList = new ArrayList(); VM vm = new VM(); - TrackDatabase trackDetailDB = new TrackDatabase( WorldManager.instance.detaildDB ); - TrackDatabase trackChainDb = new TrackDatabase( WorldManager.instance.chainDB); - TrackTrie trackStateDB = new TrackTrie(WorldManager.instance.worldState ); + Repository tractRepository = WorldManager.instance.repository.getTrack(); Program program = new Program(code , - ProgramInvokeFactory.createProgramInvoke(tx, lastBlock, contractDetails, - trackDetailDB, trackChainDb, trackStateDB)); + ProgramInvokeFactory.createProgramInvoke(tx, lastBlock, tractRepository)); program.addListener(this); program.fullTrace(); vm.play(program); - trackDetailDB.rollbackTrack(); - trackChainDb.rollbackTrack(); - trackStateDB.rollbackTrack(); - + tractRepository.rollback(); doGUI(); } @@ -155,11 +146,11 @@ public class ProgramPlayDialog extends JPanel implements ActionListener, * this method should be invoked from the * event-dispatching thread. */ - public static void createAndShowGUI(byte[] runCode, Transaction tx, Block lastBlock, ContractDetails details) { + public static void createAndShowGUI(byte[] runCode, Transaction tx, Block lastBlock) { ProgramPlayDialog ppd; if (tx != null) - ppd = new ProgramPlayDialog(runCode, tx, lastBlock, details); + ppd = new ProgramPlayDialog(runCode, tx, lastBlock); else{ ppd = new ProgramPlayDialog(runCode); } @@ -204,7 +195,7 @@ public class ProgramPlayDialog extends JPanel implements ActionListener, SwingUtilities.invokeLater(new Runnable() { public void run() { - createAndShowGUI(code, null, null, null); + createAndShowGUI(code, null, null); } }); diff --git a/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java b/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java index db428340..1d43e540 100644 --- a/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java +++ b/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java @@ -4,6 +4,7 @@ import org.ethereum.core.*; import org.ethereum.crypto.ECKey; import org.ethereum.crypto.HashUtil; import org.ethereum.db.DatabaseImpl; +import org.ethereum.db.Repository; import org.ethereum.db.TrackDatabase; import org.ethereum.trie.TrackTrie; import org.ethereum.trie.Trie; @@ -43,10 +44,8 @@ public class WorldManager { Collections.synchronizedMap(new HashMap()); public DatabaseImpl chainDB = new DatabaseImpl("blockchain"); - public DatabaseImpl stateDB = new DatabaseImpl("state"); - public DatabaseImpl detaildDB = new DatabaseImpl("details"); - public Trie worldState = new Trie(stateDB.getDb()); + public Repository repository = new Repository(); public static WorldManager instance = new WorldManager(); public WorldManager() { @@ -84,19 +83,21 @@ public class WorldManager { // 1. VALIDATE THE NONCE byte[] senderAddress = tx.getSender(); - byte[] stateData = worldState.get(senderAddress); - if (stateData == null || stateData.length == 0) { + AccountState senderAccount = repository.getAccountState(senderAddress); + + if (senderAccount == null) { if (stateLogger.isWarnEnabled()) stateLogger.warn("No such address: {}", Hex.toHexString(senderAddress)); return; } - AccountState senderState = new AccountState(stateData); - if (senderState.getNonce().compareTo(new BigInteger(tx.getNonce())) != 0) { + + BigInteger nonce = repository.getNonce(senderAddress); + if (nonce.compareTo(new BigInteger(tx.getNonce())) != 0) { if (stateLogger.isWarnEnabled()) stateLogger.warn("Invalid nonce account.nonce={} tx.nonce={}", - senderState.getNonce(), new BigInteger(tx.getNonce())); + nonce.longValue(), new BigInteger(tx.getNonce())); return; } @@ -104,8 +105,9 @@ public class WorldManager { // (THIS STAGE IS NOT REVERTED BY ANY EXCEPTION) // first of all debit the gas from the issuer - AccountState receiverState = null; BigInteger gasDebit = tx.getTotalGasValueDebit(); + gasDebit = gasDebit.multiply(new BigInteger(tx.getGasPrice())); + byte[] contractAddress; // Contract creation or existing Contract call @@ -113,32 +115,27 @@ public class WorldManager { // credit the receiver contractAddress = tx.getContractAddress(); - receiverState = new AccountState(); - worldState.update(contractAddress, receiverState.getEncoded()); + repository.createAccount(contractAddress); stateLogger.info("New contract created address={}", Hex.toHexString(contractAddress)); } else { contractAddress = tx.getReceiveAddress(); - byte[] accountData = this.worldState.get(tx.getReceiveAddress()); - if (accountData.length == 0){ - receiverState = new AccountState(); + AccountState receiverState = repository.getAccountState(tx.getReceiveAddress()); + + if (receiverState == null){ + repository.createAccount(tx.getReceiveAddress()); if (stateLogger.isInfoEnabled()) stateLogger.info("New account created address={}", Hex.toHexString(tx.getReceiveAddress())); - } else { - receiverState = new AccountState(accountData); - if (stateLogger.isInfoEnabled()) - stateLogger.info("Account found address={}", - Hex.toHexString(tx.getReceiveAddress())); } } // 2.2 UPDATE THE NONCE // (THIS STAGE IS NOT REVERTED BY ANY EXCEPTION) - if (senderState.getBalance().compareTo(BigInteger.ZERO) == 1) { - senderState.incrementNonce(); - worldState.update(tx.getSender(), senderState.getEncoded()); + BigInteger balance = repository.getBalance(senderAddress); + if (balance.compareTo(BigInteger.ZERO) == 1) { + repository.increaseNonce(senderAddress); if(stateLogger.isInfoEnabled()) stateLogger.info("Before contract execution the sender address debit with gas total cost, " + @@ -153,34 +150,30 @@ public class WorldManager { // can be validate using GAS op if (gasDebit.signum() == 1){ - if (senderState.getBalance().subtract(gasDebit).signum() == -1){ + if (balance.compareTo( gasDebit ) == -1){ logger.info("No gas to start the execution: sender={}" , Hex.toHexString(tx.getSender())); return; } - senderState.addToBalance(gasDebit.negate()); - worldState.update(senderAddress, senderState.getEncoded()); + repository.addBalance(senderAddress, gasDebit.negate()); } // 3. START TRACKING FOR REVERT CHANGES OPTION !!! - TrackDatabase trackDetailDB = new TrackDatabase( WorldManager.instance.detaildDB ); - TrackDatabase trackChainDb = new TrackDatabase( WorldManager.instance.chainDB); - TrackTrie trackStateDB = new TrackTrie(WorldManager.instance.worldState ); - - trackDetailDB.startTrack(); - trackChainDb.startTrack(); - trackStateDB.startTrack(); + Repository trackRepository = repository.getTrack(); + trackRepository.startTracking(); try { // 4. THE SIMPLE VALUE/BALANCE CHANGE if(tx.getValue() != null) { - if (senderState.getBalance().subtract(new BigInteger(1, tx.getValue())).signum() >= 0){ - receiverState.addToBalance(new BigInteger(1, tx.getValue())); - senderState.addToBalance(new BigInteger(1, tx.getValue()).negate()); + BigInteger senderBalance = repository.getBalance(senderAddress); + BigInteger contractBalance = repository.getBalance(contractAddress); - trackStateDB.update(senderAddress, senderState.getEncoded()); - trackStateDB.update(contractAddress, receiverState.getEncoded()); + + if ( senderBalance.compareTo(new BigInteger(1, tx.getValue())) >= 0){ + + repository.addBalance(contractAddress, new BigInteger(1, tx.getValue())); + repository.addBalance(senderAddress, new BigInteger(1, tx.getValue()).negate()); if (stateLogger.isInfoEnabled()) stateLogger.info("Update value balance \n " + @@ -200,7 +193,7 @@ public class WorldManager { blockChain.getLastBlock(); ProgramInvoke programInvoke = - ProgramInvokeFactory.createProgramInvoke(tx, lastBlock, null, trackDetailDB, trackChainDb, trackStateDB); + ProgramInvokeFactory.createProgramInvoke(tx, lastBlock, trackRepository); if (logger.isInfoEnabled()) logger.info("running the init for contract: addres={}" , @@ -211,14 +204,12 @@ public class WorldManager { Program program = new Program(initCode, programInvoke); vm.play(program); ProgramResult result = program.getResult(); - applyProgramResult(result, gasDebit, senderState, receiverState, senderAddress, tx.getContractAddress()); + applyProgramResult(result, gasDebit, trackRepository, senderAddress, tx.getContractAddress()); } else { - if (receiverState.getCodeHash() != HashUtil.EMPTY_DATA_HASH){ - - byte[] programCode = chainDB.get(receiverState.getCodeHash()); - if (programCode != null && programCode.length != 0){ + byte[] programCode = trackRepository.getCode(tx.getReceiveAddress()); + if (programCode != null){ Block lastBlock = blockChain.getLastBlock(); @@ -227,36 +218,24 @@ public class WorldManager { logger.info("calling for existing contract: addres={}" , Hex.toHexString(tx.getReceiveAddress())); - // FETCH THE SAVED STORAGE - ContractDetails details = null; - byte[] detailsRLPData = detaildDB.get(tx.getReceiveAddress()); - if (detailsRLPData.length > 0) - details = new ContractDetails(detailsRLPData); - ProgramInvoke programInvoke = - ProgramInvokeFactory.createProgramInvoke(tx, lastBlock, details, trackDetailDB, trackChainDb, trackStateDB); + ProgramInvokeFactory.createProgramInvoke(tx, lastBlock, trackRepository); VM vm = new VM(); Program program = new Program(programCode, programInvoke); vm.play(program); ProgramResult result = program.getResult(); - applyProgramResult(result, gasDebit, senderState, receiverState, senderAddress, tx.getReceiveAddress()); - } + applyProgramResult(result, gasDebit, trackRepository, senderAddress, tx.getReceiveAddress()); } } } catch (RuntimeException e) { - trackDetailDB.rollbackTrack(); - trackChainDb.rollbackTrack(); - trackStateDB.rollbackTrack(); + trackRepository.rollback(); return; } - trackDetailDB.commitTrack(); - trackChainDb.commitTrack(); - trackStateDB.commitTrack(); - + trackRepository.commit(); pendingTransactions.put(Hex.toHexString(tx.getHash()), tx); } @@ -268,13 +247,11 @@ public class WorldManager { * * @param result * @param gasDebit - * @param senderState - * @param receiverState * @param senderAddress * @param contractAddress */ private void applyProgramResult(ProgramResult result, BigInteger gasDebit, - AccountState senderState, AccountState receiverState, + Repository repository, byte[] senderAddress, byte[] contractAddress) { if (result.getException() != null && @@ -300,20 +277,17 @@ public class WorldManager { if(stateLogger.isInfoEnabled()) stateLogger.info("After contract execution the sender address refunded with gas leftover , \n sender={} \n contract={} \n gas_refund= {}", Hex.toHexString(senderAddress) ,Hex.toHexString(contractAddress), refund); - senderState.addToBalance(refund); - worldState.update(senderAddress, senderState.getEncoded()); + + repository.addBalance(senderAddress, refund); } if (bodyCode != null){ - byte[] codeKey = HashUtil.sha3(bodyCode); - chainDB.put(codeKey, bodyCode); - receiverState.setCodeHash(codeKey); - worldState.update(contractAddress, receiverState.getEncoded()); + repository.saveCode(contractAddress, bodyCode); + if (stateLogger.isInfoEnabled()) - stateLogger.info("saving code of the contract to the db:\n contract={} sha3(code)={} code={}", + stateLogger.info("saving code of the contract to the db:\n contract={} code={}", Hex.toHexString(contractAddress), - Hex.toHexString(codeKey), Hex.toHexString(bodyCode)); } @@ -346,6 +320,6 @@ public class WorldManager { public void close() { chainDB.close(); - stateDB.close(); + repository.close(); } } diff --git a/ethereumj-core/src/main/java/org/ethereum/vm/Program.java b/ethereumj-core/src/main/java/org/ethereum/vm/Program.java index e7a2f861..32746c08 100644 --- a/ethereumj-core/src/main/java/org/ethereum/vm/Program.java +++ b/ethereumj-core/src/main/java/org/ethereum/vm/Program.java @@ -1,12 +1,8 @@ package org.ethereum.vm; -import org.ethereum.core.AccountState; -import org.ethereum.core.ContractDetails; import org.ethereum.crypto.HashUtil; -import org.ethereum.db.TrackDatabase; -import org.ethereum.manager.WorldManager; -import org.ethereum.trie.TrackTrie; -import org.ethereum.util.RLP; +import org.ethereum.db.ContractDetails; +import org.ethereum.db.Repository; import org.ethereum.util.Utils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -14,7 +10,8 @@ import org.spongycastle.util.encoders.Hex; import java.math.BigInteger; import java.nio.ByteBuffer; -import java.util.*; +import java.util.Arrays; +import java.util.Stack; /** * www.ethereumJ.com @@ -28,8 +25,8 @@ public class Program { ProgramListener listener; Stack stack = new Stack(); - Map storage = new HashMap(); ByteBuffer memory = null; + byte[] programAddress; ProgramResult result = new ProgramResult(); @@ -44,18 +41,14 @@ public class Program { gasLogger = LoggerFactory.getLogger("gas - " + invokeData.hashCode()); - result.setStateDb(invokeData.getStateDb()); - result.setChainDb(invokeData.getChainDb()); - result.setDetailDB(invokeData.getDetaildDB()); + result.setRepository(invokeData.getRepository()); if (ops == null) throw new RuntimeException("program can not run with ops: null"); this.invokeData = invokeData; this.ops = ops; - if (invokeData.getStorage() != null){ - storage = invokeData.getStorage(); - } + programAddress = invokeData.getOwnerAddress().getNoLeadZeroesData(); } public byte getCurrentOp(){ @@ -229,22 +222,12 @@ public class Program { // 1. FETCH THE CODE FROM THE MEMORY ByteBuffer programCode = memoryChunk(memStart, memSize); - TrackTrie stateDB = new TrackTrie( result.getStateDb() ); - TrackDatabase chainDB = new TrackDatabase( result.getChainDb() ); - TrackDatabase detailDB = new TrackDatabase( result.getDetailDB() ); - - detailDB.startTrack(); - chainDB.startTrack(); - stateDB.startTrack(); - - if (logger.isInfoEnabled()) - logger.info("creating a new contract"); + Repository trackRepository = result.getRepository().getTrack(); + trackRepository.startTracking(); byte[] senderAddress = this.getOwnerAddress().getNoLeadZeroesData(); - - byte[] data = stateDB.get( senderAddress ); - AccountState senderState = new AccountState(data); - + if (logger.isInfoEnabled()) + logger.info("creating a new contract inside contract run: [{}]", Hex.toHexString(senderAddress)); // 2.1 PERFORM THE GAS VALUE TX // (THIS STAGE IS NOT REVERTED BY ANY EXCEPTION) @@ -259,19 +242,17 @@ public class Program { } // 2.2 CREATE THE CONTRACT ADDRESS - byte[] nonce = senderState.getNonce().toByteArray(); + byte[] nonce = trackRepository.getNonce(senderAddress).toByteArray(); byte[] newAddress = HashUtil.calcNewAddr(this.getOwnerAddress().getNoLeadZeroesData(), nonce); // 2.3 UPDATE THE NONCE // (THIS STAGE IS NOT REVERTED BY ANY EXCEPTION) - senderState.incrementNonce(); + trackRepository.increaseNonce(senderAddress); // 3. COOK THE INVOKE AND EXECUTE ProgramInvoke programInvoke = - ProgramInvokeFactory.createProgramInvoke(this, DataWord.ZERO, null, - DataWord.ZERO, gas, BigInteger.ZERO, - null, - detailDB, chainDB, stateDB); + ProgramInvokeFactory.createProgramInvoke(this, DataWord.ZERO, DataWord.ZERO, + gas, BigInteger.ZERO, null, trackRepository); VM vm = new VM(); Program program = new Program(programCode.array(), programInvoke); @@ -282,31 +263,18 @@ public class Program { result.getException() instanceof Program.OutOfGasException){ logger.info("contract run halted by OutOfGas: new contract init ={}" , Hex.toHexString(newAddress)); - detailDB.rollbackTrack(); - chainDB.rollbackTrack(); - stateDB.rollbackTrack(); + trackRepository.rollback(); stackPushZero(); return; } // 4. CREATE THE CONTRACT OUT OF RETURN byte[] code = result.getHReturn().array(); - byte[] keyCode = HashUtil.sha3(code); + trackRepository.saveCode(newAddress, code); - ContractDetails contractDetails = new ContractDetails(program.storage); - AccountState state = new AccountState(); - state.setCodeHash(keyCode); - - stateDB.update(newAddress, state.getEncoded()); - chainDB.put(keyCode, code); - detailDB.put(newAddress, contractDetails.getEncoded()); - - // IN SUCCESS PUSH THE ADDRESS IN THE STACK + // IN SUCCESS PUSH THE ADDRESS INTO THE STACK stackPush(new DataWord(newAddress)); - - detailDB.commitTrack(); - chainDB.commitTrack(); - stateDB.commitTrack(); + trackRepository.commit(); } /** @@ -327,26 +295,11 @@ public class Program { ByteBuffer data = memoryChunk(inDataOffs, inDataSize); // FETCH THE SAVED STORAGE - ContractDetails details = null; byte[] toAddress = toAddressDW.getNoLeadZeroesData(); - byte[] detailsRLPData = invokeData.getDetaildDB().get(toAddress); - if (detailsRLPData != null && detailsRLPData.length > 0) - details = new ContractDetails(detailsRLPData); - - AccountState receiverState; - byte[] accountData = result.getStateDb().get(toAddress); - if (accountData == null || accountData.length == 0){ - - logger.info("no saved address in db to call: address={}" ,Hex.toHexString(toAddress)); - return; - } else{ - - receiverState = new AccountState(accountData); - } // FETCH THE CODE - byte[] programCode = result.getChainDb().get(receiverState.getCodeHash()); + byte[] programCode = this.result.getRepository().getCode(toAddress); if (programCode != null && programCode.length != 0){ if (logger.isInfoEnabled()) @@ -354,14 +307,6 @@ public class Program { Hex.toHexString(toAddress)); byte[] senderAddress = this.getOwnerAddress().getNoLeadZeroesData(); - byte[] senderStateB = this.result.getStateDb().get(senderAddress); - if (senderStateB == null){ - logger.info("This should not happen in any case, this inside contract run is is evidence for contract to exist: \n" + - "address={}", Hex.toHexString(senderAddress)); - return; - } - - AccountState senderState = new AccountState(senderStateB); // 2.1 PERFORM THE GAS VALUE TX // (THIS STAGE IS NOT REVERTED BY ANY EXCEPTION) @@ -376,29 +321,19 @@ public class Program { // 2.2 UPDATE THE NONCE // (THIS STAGE IS NOT REVERTED BY ANY EXCEPTION) - senderState.incrementNonce(); + this.result.repository.increaseNonce(senderAddress); - TrackTrie stateDB = new TrackTrie( result.getStateDb() ); - TrackDatabase chainDB = new TrackDatabase( result.getChainDb() ); - TrackDatabase detailDB = new TrackDatabase( result.getDetailDB() ); - - detailDB.startTrack(); - chainDB.startTrack(); - stateDB.startTrack(); + Repository trackRepository = result.getRepository().getTrack(); + trackRepository.startTracking(); // todo: check if the endowment can really be done - receiverState.addToBalance(endowmentValue.value()); - stateDB.update(toAddress, receiverState.getEncoded()); - - Map storage = null; - if (details != null) - storage = details.getStorage(); + trackRepository.addBalance(toAddress, endowmentValue.value()); ProgramInvoke programInvoke = - ProgramInvokeFactory.createProgramInvoke(this, toAddressDW, storage, - endowmentValue, gas, receiverState.getBalance(), + ProgramInvokeFactory.createProgramInvoke(this, toAddressDW, + endowmentValue, gas, result.getRepository().getBalance(toAddress), data.array(), - detailDB, chainDB, stateDB); + trackRepository); VM vm = new VM(); Program program = new Program(programCode, programInvoke); @@ -409,9 +344,7 @@ public class Program { result.getException() instanceof Program.OutOfGasException){ logger.info("contract run halted by OutOfGas: contract={}" , Hex.toHexString(toAddress)); - detailDB.rollbackTrack(); - chainDB.rollbackTrack(); - stateDB.rollbackTrack(); + trackRepository.rollback(); stackPushZero(); return; } @@ -434,9 +367,7 @@ public class Program { // 4. THE FLAG OF SUCCESS IS ONE PUSHED INTO THE STACK stackPushOne(); - detailDB.commitTrack(); - chainDB.commitTrack(); - stateDB.commitTrack(); + trackRepository.commit(); stackPush(new DataWord(1)); // the gas spent in any internal outcome @@ -444,13 +375,6 @@ public class Program { spendGas(result.getGasUsed(), " 'Total for CALL run' "); logger.info("The usage of the gas in external call updated", result.getGasUsed()); - // update the storage , it could - // change by the call - byte[] contractDetailBytes = - result.getDetailDB().get(getOwnerAddress().getNoLeadZeroesData()); - if (contractDetailBytes != null){ - this.storage = new ContractDetails(contractDetailBytes).getStorage(); - } } } @@ -473,12 +397,7 @@ public class Program { public void storageSave(byte[] key, byte[] val){ DataWord keyWord = new DataWord(key); DataWord valWord = new DataWord(val); - storage.put(keyWord, valWord); - - if (storage != null){ - ContractDetails contractDetails = new ContractDetails(storage); - result.getDetailDB().put(getOwnerAddress().getNoLeadZeroesData() , contractDetails.getEncoded()); - } + result.repository.addStorageRow(this.programAddress, keyWord, valWord); } public DataWord getOwnerAddress(){ @@ -536,7 +455,7 @@ public class Program { } public DataWord storageLoad(DataWord key){ - return storage.get(key); + return result.repository.getStorageValue(this.programAddress, key); } public DataWord getPrevHash(){ @@ -584,10 +503,12 @@ public class Program { } if (stackData.length() > 0) stackData.insert(0, "\n"); + ContractDetails contractDetails = this.result.getRepository().getContractDetails(this.programAddress); StringBuilder storageData = new StringBuilder(); - for (DataWord key : storage.keySet()){ + for (DataWord key : contractDetails.getStorage().keySet()){ - storageData.append(" ").append(key).append(" -> ").append(storage.get(key)).append("\n"); + storageData.append(" ").append(key).append(" -> "). + append(contractDetails.getStorage().get(key)).append("\n"); } if (storageData.length() > 0) storageData.insert(0, "\n"); diff --git a/ethereumj-core/src/main/java/org/ethereum/vm/ProgramInvoke.java b/ethereumj-core/src/main/java/org/ethereum/vm/ProgramInvoke.java index fad8a278..cdf52ae1 100644 --- a/ethereumj-core/src/main/java/org/ethereum/vm/ProgramInvoke.java +++ b/ethereumj-core/src/main/java/org/ethereum/vm/ProgramInvoke.java @@ -1,5 +1,6 @@ package org.ethereum.vm; +import org.ethereum.db.Repository; import org.ethereum.db.TrackDatabase; import org.ethereum.trie.TrackTrie; @@ -32,11 +33,7 @@ public interface ProgramInvoke { public DataWord getDifficulty(); public DataWord getGaslimit(); - public Map getStorage(); - - public TrackDatabase getDetaildDB(); - public TrackDatabase getChainDb(); - public TrackTrie getStateDb(); + public Repository getRepository(); public boolean byTransaction(); diff --git a/ethereumj-core/src/main/java/org/ethereum/vm/ProgramInvokeFactory.java b/ethereumj-core/src/main/java/org/ethereum/vm/ProgramInvokeFactory.java index 54062eda..0614d596 100644 --- a/ethereumj-core/src/main/java/org/ethereum/vm/ProgramInvokeFactory.java +++ b/ethereumj-core/src/main/java/org/ethereum/vm/ProgramInvokeFactory.java @@ -1,18 +1,13 @@ package org.ethereum.vm; -import org.ethereum.core.AccountState; import org.ethereum.core.Block; -import org.ethereum.core.ContractDetails; import org.ethereum.core.Transaction; -import org.ethereum.db.TrackDatabase; -import org.ethereum.manager.WorldManager; -import org.ethereum.trie.TrackTrie; +import org.ethereum.db.Repository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.spongycastle.util.encoders.Hex; import java.math.BigInteger; -import java.util.Map; /** * www.ethereumJ.com @@ -26,8 +21,7 @@ public class ProgramInvokeFactory { private static Logger logger = LoggerFactory.getLogger("VM"); // Invocation by the wire tx - public static ProgramInvoke createProgramInvoke(Transaction tx, Block lastBlock, ContractDetails details, - TrackDatabase detaildDB, TrackDatabase chainDb, TrackTrie stateDB){ + public static ProgramInvoke createProgramInvoke(Transaction tx, Block lastBlock, Repository repository){ // https://ethereum.etherpad.mozilla.org/26 @@ -44,13 +38,7 @@ public class ProgramInvokeFactory { byte[] caller = tx.getSender(); /*** BALANCE op ***/ - byte[] addressStateData = stateDB.get(address); - - byte[] balance = null; - if (addressStateData.length == 0) - balance = new byte[]{0}; - else - balance = new AccountState(addressStateData).getBalance().toByteArray(); + byte[] balance = repository.getBalance(address).toByteArray(); /*** GASPRICE op ***/ @@ -87,14 +75,8 @@ public class ProgramInvokeFactory { /*** GASLIMIT op ***/ long gaslimit = lastBlock.getGasLimit(); - /*** Map of storage values ***/ - Map storage = null; - if (details != null) - storage = details.getStorage(); - detaildDB.startTrack(); - chainDb.startTrack(); - stateDB.startTrack(); + repository.startTracking(); if (logger.isInfoEnabled()){ logger.info("Program invocation: \n" + @@ -132,8 +114,8 @@ public class ProgramInvokeFactory { ProgramInvoke programInvoke = new ProgramInvokeImpl(address, origin, caller, balance, gasPrice, gas, callValue, data, - lastHash, coinbase, timestamp, number, difficulty, gaslimit, storage, - detaildDB, chainDb, stateDB); + lastHash, coinbase, timestamp, number, difficulty, gaslimit, + repository); return programInvoke; } @@ -143,10 +125,9 @@ public class ProgramInvokeFactory { * This invocation created for contract call contract */ public static ProgramInvoke createProgramInvoke(Program program, DataWord toAddress, - Map storageIn, DataWord inValue, DataWord inGas, BigInteger balanceInt, byte[] dataIn, - TrackDatabase detailDB, TrackDatabase chainDB, TrackTrie stateDB){ + Repository repository){ DataWord address = toAddress; @@ -166,8 +147,6 @@ public class ProgramInvokeFactory { DataWord difficulty = program.getDifficulty(); DataWord gasLimit = program.getGaslimit(); - Map storage = storageIn; - if (logger.isInfoEnabled()){ logger.info("Program invocation: \n" + @@ -204,7 +183,7 @@ public class ProgramInvokeFactory { return new ProgramInvokeImpl(address, origin, caller, balance, gasPrice, gas, callValue, data, lastHash, coinbase, timestamp, number, difficulty, gasLimit, - storage, detailDB, chainDB, stateDB); + repository); } } diff --git a/ethereumj-core/src/main/java/org/ethereum/vm/ProgramInvokeImpl.java b/ethereumj-core/src/main/java/org/ethereum/vm/ProgramInvokeImpl.java index 183eaf8b..9b6f99bb 100644 --- a/ethereumj-core/src/main/java/org/ethereum/vm/ProgramInvokeImpl.java +++ b/ethereumj-core/src/main/java/org/ethereum/vm/ProgramInvokeImpl.java @@ -1,5 +1,6 @@ package org.ethereum.vm; +import org.ethereum.db.Repository; import org.ethereum.db.TrackDatabase; import org.ethereum.trie.TrackTrie; import org.ethereum.util.ByteUtil; @@ -36,16 +37,13 @@ public class ProgramInvokeImpl implements ProgramInvoke { Map storage; - TrackDatabase detaildDB; - TrackDatabase chainDb; - TrackTrie stateDb; + Repository repository; private boolean byTransaction = true; public ProgramInvokeImpl(DataWord address, DataWord origin, DataWord caller, DataWord balance, DataWord gasPrice, DataWord gas, DataWord callValue, byte[] msgData, DataWord lastHash, DataWord coinbase, DataWord timestamp, DataWord number, DataWord difficulty, - DataWord gaslimit, Map storage, - TrackDatabase detaildDB, TrackDatabase chainDb, TrackTrie stateDB) { + DataWord gaslimit, Repository repository) { // Transaction env this.address = address; @@ -67,9 +65,7 @@ public class ProgramInvokeImpl implements ProgramInvoke { this.storage = storage; - this.detaildDB = detaildDB; - this.chainDb = chainDb; - this.stateDb = stateDB; + this.repository = repository; this.byTransaction = false; } @@ -78,8 +74,8 @@ public class ProgramInvokeImpl implements ProgramInvoke { public ProgramInvokeImpl(byte[] address, byte[] origin, byte[] caller, byte[] balance, byte[] gasPrice, byte[] gas, byte[] callValue, byte[] msgData, byte[] lastHash, byte[] coinbase, long timestamp, long number, byte[] difficulty, - long gaslimit, Map storage, - TrackDatabase detaildDB, TrackDatabase chainDb, TrackTrie stateDB) { + long gaslimit, + Repository repository) { // Transaction env this.address = new DataWord(address); @@ -101,9 +97,7 @@ public class ProgramInvokeImpl implements ProgramInvoke { this.storage = storage; - this.detaildDB = detaildDB; - this.chainDb = chainDb; - this.stateDb = stateDB; + this.repository = repository; } /* ADDRESS op */ @@ -225,17 +219,8 @@ public class ProgramInvokeImpl implements ProgramInvoke { /* Storage */ public Map getStorage(){ return storage; } - - public TrackDatabase getDetaildDB() { - return detaildDB; - } - - public TrackDatabase getChainDb() { - return chainDb; - } - - public TrackTrie getStateDb() { - return stateDb; + public Repository getRepository() { + return repository; } @Override @@ -255,9 +240,7 @@ public class ProgramInvokeImpl implements ProgramInvoke { if (balance != null ? !balance.equals(that.balance) : that.balance != null) return false; if (callValue != null ? !callValue.equals(that.callValue) : that.callValue != null) return false; if (caller != null ? !caller.equals(that.caller) : that.caller != null) return false; - if (chainDb != null ? !chainDb.equals(that.chainDb) : that.chainDb != null) return false; if (coinbase != null ? !coinbase.equals(that.coinbase) : that.coinbase != null) return false; - if (detaildDB != null ? !detaildDB.equals(that.detaildDB) : that.detaildDB != null) return false; if (difficulty != null ? !difficulty.equals(that.difficulty) : that.difficulty != null) return false; if (gas != null ? !gas.equals(that.gas) : that.gas != null) return false; if (gasPrice != null ? !gasPrice.equals(that.gasPrice) : that.gasPrice != null) return false; @@ -266,7 +249,7 @@ public class ProgramInvokeImpl implements ProgramInvoke { if (number != null ? !number.equals(that.number) : that.number != null) return false; if (origin != null ? !origin.equals(that.origin) : that.origin != null) return false; if (prevHash != null ? !prevHash.equals(that.prevHash) : that.prevHash != null) return false; - if (stateDb != null ? !stateDb.equals(that.stateDb) : that.stateDb != null) return false; + if (repository != null ? !repository.equals(that.repository) : that.repository != null) return false; if (storage != null ? !storage.equals(that.storage) : that.storage != null) return false; if (timestamp != null ? !timestamp.equals(that.timestamp) : that.timestamp != null) return false; @@ -290,9 +273,7 @@ public class ProgramInvokeImpl implements ProgramInvoke { result = 31 * result + (difficulty != null ? difficulty.hashCode() : 0); result = 31 * result + (gaslimit != null ? gaslimit.hashCode() : 0); result = 31 * result + (storage != null ? storage.hashCode() : 0); - result = 31 * result + (detaildDB != null ? detaildDB.hashCode() : 0); - result = 31 * result + (chainDb != null ? chainDb.hashCode() : 0); - result = 31 * result + (stateDb != null ? stateDb.hashCode() : 0); + result = 31 * result + (repository!= null ? repository.hashCode() : 0); result = 31 * result + (byTransaction ? 1 : 0); return result; } diff --git a/ethereumj-core/src/main/java/org/ethereum/vm/ProgramInvokeMockImpl.java b/ethereumj-core/src/main/java/org/ethereum/vm/ProgramInvokeMockImpl.java index 087ba785..48c369e0 100644 --- a/ethereumj-core/src/main/java/org/ethereum/vm/ProgramInvokeMockImpl.java +++ b/ethereumj-core/src/main/java/org/ethereum/vm/ProgramInvokeMockImpl.java @@ -1,15 +1,10 @@ package org.ethereum.vm; -import org.ethereum.core.ContractDetails; import org.ethereum.crypto.ECKey; import org.ethereum.crypto.HashUtil; -import org.ethereum.db.TrackDatabase; -import org.ethereum.manager.WorldManager; -import org.ethereum.trie.TrackTrie; +import org.ethereum.db.Repository; import org.spongycastle.util.encoders.Hex; -import java.util.Map; - /** * www.ethereumJ.com * @author: Roman Mandeleil @@ -20,20 +15,18 @@ public class ProgramInvokeMockImpl implements ProgramInvoke { byte[] msgData; - TrackTrie stateDB = null; - TrackDatabase chainDb = null; - TrackDatabase detaildDB = null; - - ContractDetails details = null; - - String ownerAddress; + Repository repository = null; + String ownerAddress = "cd2a3d9f938e13cd947ec05abc7fe734df8dd826"; public ProgramInvokeMockImpl(byte[] msgDataRaw){ + this(); this.msgData = msgDataRaw; } public ProgramInvokeMockImpl() { + this.repository = new Repository(); + this.repository.createAccount(Hex.decode(ownerAddress)); } /* ADDRESS op */ @@ -171,51 +164,21 @@ public class ProgramInvokeMockImpl implements ProgramInvoke { return new DataWord(gasLimit); } - - public void setStateDB(TrackTrie stateDB) { - this.stateDB = stateDB; - } - - public void setChainDb(TrackDatabase chainDb) { - this.chainDb = chainDb; - } - - public void setDetaildDB(TrackDatabase detaildDB) { - this.detaildDB = detaildDB; - } - - public void setDetails(ContractDetails details) { - this.details = details; - } - public void setOwnerAddress(String ownerAddress) { this.ownerAddress = ownerAddress; } - - @Override - public Map getStorage() { - if (details == null) return null; - return details.getStorage(); - } - - @Override - public TrackDatabase getDetaildDB() { - return detaildDB; - } - - @Override - public TrackDatabase getChainDb() { - return chainDb; - } - - @Override - public TrackTrie getStateDb() { - return stateDB; - } - @Override public boolean byTransaction() { return true; } + + @Override + public Repository getRepository() { + return this.repository; + } + + public void setRepository(Repository repository) { + this.repository = repository; + } } diff --git a/ethereumj-core/src/main/java/org/ethereum/vm/ProgramResult.java b/ethereumj-core/src/main/java/org/ethereum/vm/ProgramResult.java index 967599c4..d90a5a5e 100644 --- a/ethereumj-core/src/main/java/org/ethereum/vm/ProgramResult.java +++ b/ethereumj-core/src/main/java/org/ethereum/vm/ProgramResult.java @@ -1,5 +1,6 @@ package org.ethereum.vm; +import org.ethereum.db.Repository; import org.ethereum.db.TrackDatabase; import org.ethereum.trie.TrackTrie; @@ -18,9 +19,7 @@ public class ProgramResult { private ByteBuffer hReturn = null; private RuntimeException exception; - TrackDatabase detailDB; - TrackDatabase chainDb; - TrackTrie stateDb; + Repository repository = null; public void spendGas(int gas){ gasUsed += gas; @@ -48,27 +47,11 @@ public class ProgramResult { this.exception = exception; } - public TrackDatabase getDetailDB() { - return detailDB; + public Repository getRepository() { + return repository; } - public void setDetailDB(TrackDatabase detailDB) { - this.detailDB = detailDB; - } - - public TrackDatabase getChainDb() { - return chainDb; - } - - public void setChainDb(TrackDatabase chainDb) { - this.chainDb = chainDb; - } - - public TrackTrie getStateDb() { - return stateDb; - } - - public void setStateDb(TrackTrie stateDb) { - this.stateDb = stateDb; + public void setRepository(Repository repository) { + this.repository = repository; } } diff --git a/ethereumj-core/src/test/java/org/ethereum/core/ContractDetailsTest.java b/ethereumj-core/src/test/java/org/ethereum/core/ContractDetailsTest.java deleted file mode 100644 index d74e3bbe..00000000 --- a/ethereumj-core/src/test/java/org/ethereum/core/ContractDetailsTest.java +++ /dev/null @@ -1,90 +0,0 @@ -package org.ethereum.core; - -import org.ethereum.vm.DataWord; -import org.junit.Assert; -import org.junit.Test; -import org.spongycastle.util.encoders.Hex; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -/** - * www.ethereumJ.com - * - * @author: Roman Mandeleil - * Created on: 09/06/2014 15:41 - */ - -public class ContractDetailsTest { - - @Test /* encode 2 keys/values */ - public void test1(){ - - String expected = "f888f842a00000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000001f842a00000000000000000000000000000000000000000000000000000000000009dd4a0000000000000000000000000000000000000000000000000000000000000765f"; - - DataWord key1 = new DataWord(1); - DataWord value1 = new DataWord(30303); - - DataWord key2 = new DataWord(2); - DataWord value2 = new DataWord(40404); - - - HashMap storage = new HashMap<>(); - storage.put(key1, value1); - storage.put(key2, value2); - - ContractDetails contractDetails = new ContractDetails(storage); - - String encoded = Hex.toHexString(contractDetails.getEncoded()); - - Assert.assertEquals(expected, encoded); - } - - @Test /* encode 3 keys/values */ - public void test2(){ - - String expected = "f8caf863a00000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000003f863a00000000000000000000000000000000000000000000000000000000000009dd4a0000000000000000000000000000000000000000000000000000000000000765fa0000000000000000000000000000000000000000000000000000000000000ffff"; - - DataWord key1 = new DataWord(1); - DataWord value1 = new DataWord(30303); - - DataWord key2 = new DataWord(2); - DataWord value2 = new DataWord(40404); - - DataWord key3 = new DataWord(3); - DataWord value3 = new DataWord(0xFFFF); - - HashMap storage = new HashMap<>(); - storage.put(key1, value1); - storage.put(key2, value2); - storage.put(key3, value3); - - ContractDetails contractDetails = new ContractDetails(storage); - - String encoded = Hex.toHexString(contractDetails.getEncoded()); - - Assert.assertEquals(expected, encoded); - } - - @Test /* decode 3 keys/values */ - public void test3(){ - - String rlpData = "f8caf863a00000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000003f863a00000000000000000000000000000000000000000000000000000000000009dd4a0000000000000000000000000000000000000000000000000000000000000765fa0000000000000000000000000000000000000000000000000000000000000ffff"; - ContractDetails contractDetails = new ContractDetails(Hex.decode(rlpData)); - - String expKey3String = "0000000000000000000000000000000000000000000000000000000000000003"; - String expVal3String = "000000000000000000000000000000000000000000000000000000000000ffff"; - - DataWord key3 = contractDetails.storageKeys.get(2); - DataWord value3 = contractDetails.storageValues.get(2); - - String key3String = Hex.toHexString(key3.getData()); - String value3String = Hex.toHexString(value3.getData()); - - Assert.assertEquals(expKey3String, key3String); - Assert.assertEquals(expVal3String, value3String); - } - - -} diff --git a/ethereumj-core/src/test/java/org/ethereum/db/RepositoryTest.java b/ethereumj-core/src/test/java/org/ethereum/db/RepositoryTest.java index 0356df93..38c4bc44 100644 --- a/ethereumj-core/src/test/java/org/ethereum/db/RepositoryTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/db/RepositoryTest.java @@ -1,7 +1,6 @@ package org.ethereum.db; import org.ethereum.core.AccountState; -import org.ethereum.core.ContractDetails; import org.ethereum.vm.DataWord; import org.junit.*; import org.junit.runners.MethodSorters; diff --git a/ethereumj-core/src/test/java/org/ethereum/vm/VMComplexTest.java b/ethereumj-core/src/test/java/org/ethereum/vm/VMComplexTest.java index c206c571..145826a0 100644 --- a/ethereumj-core/src/test/java/org/ethereum/vm/VMComplexTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/vm/VMComplexTest.java @@ -1,17 +1,14 @@ package org.ethereum.vm; -import org.abego.treelayout.internal.util.Contract; import org.ethereum.core.AccountState; -import org.ethereum.core.ContractDetails; import org.ethereum.crypto.HashUtil; -import org.ethereum.db.TrackDatabase; -import org.ethereum.manager.WorldManager; -import org.ethereum.trie.TrackTrie; +import org.ethereum.db.Repository; +import org.junit.FixMethodOrder; import org.junit.Test; +import org.junit.runners.MethodSorters; import org.spongycastle.util.encoders.Hex; import java.math.BigInteger; -import java.util.HashMap; import static org.junit.Assert.assertEquals; @@ -22,6 +19,7 @@ import static org.junit.Assert.assertEquals; * Created on: 16/06/2014 10:37 */ +@FixMethodOrder(MethodSorters.NAME_ASCENDING) public class VMComplexTest { @@ -47,12 +45,6 @@ public class VMComplexTest { DataWord key1 = new DataWord(999); DataWord value1 = new DataWord(3); - HashMap storage = new HashMap<>(); - storage.put(key1, value1); - - ContractDetails contractDetails = new ContractDetails(storage); - - // Set contract into Database String callerAddr = "cd2a3d9f938e13cd947ec05abc7fe734df8dd826"; String contractAddr = "77045e71a7a2c50903d88e564cd72fab11e82051"; @@ -66,24 +58,18 @@ public class VMComplexTest { AccountState accountState = new AccountState(); accountState.setCodeHash(codeKey); - AccountState callerAcountState = new AccountState(); - callerAcountState.addToBalance(new BigInteger("100000000000000000000")); - - WorldManager.instance.worldState.update(callerAddrB, callerAcountState.getEncoded()); - WorldManager.instance.worldState.update(contractAddrB, accountState.getEncoded()); - WorldManager.instance.chainDB.put(codeKey, codeB); - WorldManager.instance.detaildDB.put(contractAddrB, contractDetails.getEncoded()); - - TrackTrie stateDB = new TrackTrie(WorldManager.instance.worldState); - TrackDatabase chainDb = new TrackDatabase(WorldManager.instance.chainDB); - TrackDatabase detaildDB = new TrackDatabase(WorldManager.instance.detaildDB); - ProgramInvokeMockImpl pi = new ProgramInvokeMockImpl(); - pi.setDetaildDB(detaildDB); - pi.setChainDb(chainDb); - pi.setStateDB(stateDB); - pi.setDetails(contractDetails); pi.setOwnerAddress("77045e71a7a2c50903d88e564cd72fab11e82051"); + 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 @@ -100,15 +86,15 @@ public class VMComplexTest { System.out.println(); System.out.println("============ Results ============"); - AccountState as = - new AccountState(WorldManager.instance.worldState.get( - Hex.decode( contractAddr) )); + + BigInteger balance = repository.getBalance(callerAddrB); System.out.println("*** Used gas: " + program.result.getGasUsed()); - System.out.println("*** Contract Balance: " + as.getBalance()); + System.out.println("*** Contract Balance: " + balance); // todo: assert caller balance after contract exec + repository.close(); assertEquals(expectedGas, program.result.getGasUsed()); } @@ -153,34 +139,23 @@ public class VMComplexTest { byte[] contractA_addr_bytes = Hex.decode(contractA_addr); byte[] codeA = Hex.decode(code_a); - byte[] codeA_Key = HashUtil.sha3(codeA); - AccountState accountState_a = new AccountState(); - accountState_a.setCodeHash(codeA_Key); - WorldManager.instance.worldState.update(contractA_addr_bytes, accountState_a.getEncoded()); + + ProgramInvokeMockImpl pi = new ProgramInvokeMockImpl(); + pi.setOwnerAddress(contractB_addr); + Repository repository = pi.repository; byte[] contractB_addr_bytes = Hex.decode(contractB_addr); byte[] codeB = Hex.decode(code_b); - byte[] codeB_Key = HashUtil.sha3(codeB); - AccountState accountState_b = new AccountState(); - accountState_b.setCodeHash(codeB_Key); - WorldManager.instance.worldState.update(contractB_addr_bytes, accountState_a.getEncoded()); - AccountState callerAcountState = new AccountState(); - callerAcountState.addToBalance(new BigInteger("100000000000000000000")); - WorldManager.instance.worldState.update(caller_addr_bytes, callerAcountState.getEncoded()); + repository.createAccount(contractA_addr_bytes); + repository.saveCode(contractA_addr_bytes, codeA); - WorldManager.instance.chainDB.put(codeA_Key, codeA); + repository.createAccount(contractB_addr_bytes); + repository.saveCode(contractB_addr_bytes, codeB); - TrackTrie stateDB = new TrackTrie(WorldManager.instance.worldState); - TrackDatabase chainDb = new TrackDatabase(WorldManager.instance.chainDB); - TrackDatabase detaildDB = new TrackDatabase(WorldManager.instance.detaildDB); + repository.createAccount(caller_addr_bytes); + repository.addBalance(caller_addr_bytes, new BigInteger("100000000000000000000")); - ProgramInvokeMockImpl pi = new ProgramInvokeMockImpl(); - pi.setDetaildDB(detaildDB); - pi.setChainDb(chainDb); - pi.setStateDB(stateDB); - pi.setDetails(null); - pi.setOwnerAddress(contractB_addr); // ****************** // // Play the program // @@ -198,27 +173,20 @@ public class VMComplexTest { System.out.println(); System.out.println("============ Results ============"); - AccountState as = - new AccountState(WorldManager.instance.worldState.get( - Hex.decode( contractA_addr) )); System.out.println("*** Used gas: " + program.result.getGasUsed()); - byte[] rlpBytes = WorldManager.instance.detaildDB.get(contractA_addr_bytes); - - ContractDetails details = new ContractDetails(rlpBytes); - DataWord value_1 = details.getStorage().get(new DataWord(00)); - DataWord value_2 = details.getStorage().get(new DataWord(01)); + 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 - - } @@ -270,34 +238,22 @@ public class VMComplexTest { byte[] contractA_addr_bytes = Hex.decode(contractA_addr); byte[] codeA = Hex.decode(code_a); - byte[] codeA_Key = HashUtil.sha3(codeA); - AccountState accountState_a = new AccountState(); - accountState_a.setCodeHash(codeA_Key); - WorldManager.instance.worldState.update(contractA_addr_bytes, accountState_a.getEncoded()); byte[] contractB_addr_bytes = Hex.decode(contractB_addr); byte[] codeB = Hex.decode(code_b); - byte[] codeB_Key = HashUtil.sha3(codeB); - AccountState accountState_b = new AccountState(); - accountState_b.setCodeHash(codeB_Key); - WorldManager.instance.worldState.update(contractB_addr_bytes, accountState_a.getEncoded()); - - AccountState callerAcountState = new AccountState(); - callerAcountState.addToBalance(new BigInteger("100000000000000000000")); - WorldManager.instance.worldState.update(caller_addr_bytes, callerAcountState.getEncoded()); - - WorldManager.instance.chainDB.put(codeA_Key, codeA); - - TrackTrie stateDB = new TrackTrie(WorldManager.instance.worldState); - TrackDatabase chainDb = new TrackDatabase(WorldManager.instance.chainDB); - TrackDatabase detaildDB = new TrackDatabase(WorldManager.instance.detaildDB); ProgramInvokeMockImpl pi = new ProgramInvokeMockImpl(); - pi.setDetaildDB(detaildDB); - pi.setChainDb(chainDb); - pi.setStateDB(stateDB); - pi.setDetails(null); pi.setOwnerAddress(contractB_addr); + 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 // @@ -312,12 +268,8 @@ public class VMComplexTest { program.setRuntimeFailure(e); } - System.out.println(); System.out.println("============ Results ============"); - AccountState as = - new AccountState(WorldManager.instance.worldState.get( - Hex.decode( contractA_addr) )); System.out.println("*** Used gas: " + program.result.getGasUsed()); @@ -329,6 +281,8 @@ public class VMComplexTest { 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()); @@ -337,7 +291,6 @@ public class VMComplexTest { assertEquals(expectedVal_6, value6.longValue()); // todo: check that the value pushed after exec is 1 - } @@ -374,31 +327,20 @@ public class VMComplexTest { "005460206000f2000000000000000000000000" + "0000000000000000000000602054602960006064f0"; + ProgramInvokeMockImpl pi = new ProgramInvokeMockImpl(); + pi.setOwnerAddress(contractA_addr); + + Repository repository = pi.repository; + byte[] caller_addr_bytes = Hex.decode(callerAddr); byte[] contractA_addr_bytes = Hex.decode(contractA_addr); byte[] codeA = Hex.decode(code_a); - byte[] codeA_Key = HashUtil.sha3(codeA); - AccountState accountState_a = new AccountState(); - accountState_a.setCodeHash(codeA_Key); - WorldManager.instance.worldState.update(contractA_addr_bytes, accountState_a.getEncoded()); - AccountState callerAcountState = new AccountState(); - callerAcountState.addToBalance(new BigInteger("100000000000000000000")); - WorldManager.instance.worldState.update(caller_addr_bytes, callerAcountState.getEncoded()); + repository.createAccount(contractA_addr_bytes); + repository.saveCode(contractA_addr_bytes, codeA); - WorldManager.instance.chainDB.put(codeA_Key, codeA); - - TrackTrie stateDB = new TrackTrie(WorldManager.instance.worldState); - TrackDatabase chainDb = new TrackDatabase(WorldManager.instance.chainDB); - TrackDatabase detaildDB = new TrackDatabase(WorldManager.instance.detaildDB); - - ProgramInvokeMockImpl pi = new ProgramInvokeMockImpl(); - pi.setDetaildDB(detaildDB); - pi.setChainDb(chainDb); - pi.setStateDB(stateDB); - pi.setDetails(null); - pi.setOwnerAddress(contractA_addr); + repository.createAccount(caller_addr_bytes); // ****************** // // Play the program // @@ -416,16 +358,11 @@ public class VMComplexTest { System.out.println(); System.out.println("============ Results ============"); - AccountState as = - new AccountState(WorldManager.instance.worldState.get( - Hex.decode( contractA_addr) )); System.out.println("*** Used gas: " + program.result.getGasUsed()); - - // todo: check that the value pushed after exec is the new address - + repository.close(); } diff --git a/ethereumj-core/src/test/java/org/ethereum/vm/VMTest.java b/ethereumj-core/src/test/java/org/ethereum/vm/VMTest.java index 535d71a9..940781a9 100644 --- a/ethereumj-core/src/test/java/org/ethereum/vm/VMTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/vm/VMTest.java @@ -1,6 +1,9 @@ package org.ethereum.vm; +import org.ethereum.db.Repository; +import org.junit.FixMethodOrder; import org.junit.Test; +import org.junit.runners.MethodSorters; import org.spongycastle.util.encoders.Hex; import static org.junit.Assert.assertEquals; @@ -13,6 +16,7 @@ import static org.junit.Assert.fail; * Created on: 01/06/2014 11:05 */ +@FixMethodOrder(MethodSorters.NAME_ASCENDING) public class VMTest { @Test // PUSH1 OP @@ -25,6 +29,7 @@ public class VMTest { program.fullTrace(); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -38,6 +43,7 @@ public class VMTest { program.fullTrace(); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -51,6 +57,7 @@ public class VMTest { program.fullTrace(); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -64,6 +71,7 @@ public class VMTest { program.fullTrace(); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -77,6 +85,7 @@ public class VMTest { program.fullTrace(); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -90,6 +99,7 @@ public class VMTest { program.fullTrace(); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -103,6 +113,7 @@ public class VMTest { program.fullTrace(); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -116,6 +127,7 @@ public class VMTest { program.fullTrace(); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -129,6 +141,7 @@ public class VMTest { program.fullTrace(); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -143,6 +156,7 @@ public class VMTest { program.fullTrace(); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -156,6 +170,7 @@ public class VMTest { program.fullTrace(); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -169,6 +184,7 @@ public class VMTest { program.fullTrace(); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -182,6 +198,7 @@ public class VMTest { program.fullTrace(); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -195,6 +212,7 @@ public class VMTest { program.fullTrace(); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -208,6 +226,7 @@ public class VMTest { program.fullTrace(); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -221,6 +240,7 @@ public class VMTest { program.fullTrace(); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -234,6 +254,7 @@ public class VMTest { program.fullTrace(); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -247,6 +268,7 @@ public class VMTest { program.fullTrace(); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -260,6 +282,7 @@ public class VMTest { program.fullTrace(); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -273,6 +296,7 @@ public class VMTest { program.fullTrace(); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -286,6 +310,7 @@ public class VMTest { program.fullTrace(); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -299,6 +324,7 @@ public class VMTest { program.fullTrace(); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -312,6 +338,7 @@ public class VMTest { program.fullTrace(); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -325,6 +352,7 @@ public class VMTest { program.fullTrace(); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -338,6 +366,7 @@ public class VMTest { program.fullTrace(); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -351,6 +380,7 @@ public class VMTest { program.fullTrace(); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -364,6 +394,7 @@ public class VMTest { program.fullTrace(); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -377,6 +408,7 @@ public class VMTest { program.fullTrace(); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -390,6 +422,7 @@ public class VMTest { program.fullTrace(); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -403,6 +436,7 @@ public class VMTest { program.fullTrace(); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -416,6 +450,7 @@ public class VMTest { program.fullTrace(); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -429,6 +464,7 @@ public class VMTest { program.fullTrace(); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -442,9 +478,11 @@ public class VMTest { program.fullTrace(); vm.step(program); } catch (RuntimeException e) { + program.getResult().repository.close(); assertTrue(program.isStopped()); return; } + program.getResult().repository.close(); fail(); } @@ -459,8 +497,10 @@ public class VMTest { vm.step(program); } catch (RuntimeException e) { assertTrue(program.isStopped()); + program.getResult().repository.close(); return; } + program.getResult().repository.close(); fail(); } @@ -475,6 +515,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @@ -489,6 +530,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -502,9 +544,11 @@ public class VMTest { vm.step(program); vm.step(program); } catch (RuntimeException e) { + program.getResult().repository.close(); assertTrue(program.isStopped()); return; } + program.getResult().repository.close(); fail(); } @@ -519,6 +563,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -533,6 +578,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -546,9 +592,11 @@ public class VMTest { vm.step(program); vm.step(program); } catch (RuntimeException e) { + program.getResult().repository.close(); assertTrue(program.isStopped()); return; } + program.getResult().repository.close(); fail(); } @@ -563,6 +611,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -577,6 +626,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -591,9 +641,11 @@ public class VMTest { vm.step(program); vm.step(program); } catch (RuntimeException e) { + program.getResult().repository.close(); assertTrue(program.isStopped()); return; } + program.getResult().repository.close(); fail(); } @@ -609,6 +661,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -623,6 +676,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -637,6 +691,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -651,9 +706,11 @@ public class VMTest { vm.step(program); vm.step(program); } catch (RuntimeException e) { + program.getResult().repository.close(); assertTrue(program.isStopped()); return; } + program.getResult().repository.close(); fail(); } @@ -667,6 +724,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -680,6 +738,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -693,9 +752,11 @@ public class VMTest { vm.step(program); vm.step(program); } catch (RuntimeException e) { + program.getResult().repository.close(); assertTrue(program.isStopped()); return; } + program.getResult().repository.close(); fail(); } @@ -710,6 +771,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -724,6 +786,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -738,6 +801,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @@ -751,9 +815,11 @@ public class VMTest { vm.step(program); vm.step(program); } catch (RuntimeException e) { + program.getResult().repository.close(); assertTrue(program.isStopped()); return; } + program.getResult().repository.close(); fail(); } @@ -768,6 +834,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @@ -782,6 +849,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @@ -796,6 +864,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @@ -809,9 +878,11 @@ public class VMTest { vm.step(program); vm.step(program); } catch (RuntimeException e) { + program.getResult().repository.close(); assertTrue(program.isStopped()); return; } + program.getResult().repository.close(); fail(); } @@ -827,6 +898,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @@ -844,6 +916,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @@ -861,6 +934,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @@ -876,8 +950,10 @@ public class VMTest { vm.step(program); } catch (RuntimeException e) { assertTrue(program.isStopped()); + program.getResult().repository.close(); return; } + program.getResult().repository.close(); fail(); } @@ -894,6 +970,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @@ -908,6 +985,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @@ -922,6 +1000,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @@ -936,8 +1015,10 @@ public class VMTest { vm.step(program); } catch (RuntimeException e) { assertTrue(program.isStopped()); + program.getResult().repository.close(); return; } + program.getResult().repository.close(); fail(); } @@ -953,6 +1034,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @@ -970,6 +1052,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @@ -987,6 +1070,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @@ -1001,9 +1085,11 @@ public class VMTest { vm.step(program); vm.step(program); } catch (RuntimeException e) { + program.getResult().repository.close(); assertTrue(program.isStopped()); return; } + program.getResult().repository.close(); fail(); } @@ -1020,6 +1106,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @@ -1033,6 +1120,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @@ -1046,22 +1134,25 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @Test // NEG OP public void testNEG_4(){ + VM vm = new VM(); + Program program = new Program(Hex.decode("09"), new ProgramInvokeMockImpl()); try { - VM vm = new VM(); - Program program = new Program(Hex.decode("09"), new ProgramInvokeMockImpl()); vm.step(program); vm.step(program); } catch (RuntimeException e) { + program.getResult().repository.close(); return; } + program.getResult().repository.close(); fail(); } @@ -1078,6 +1169,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @@ -1094,6 +1186,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @@ -1111,9 +1204,11 @@ public class VMTest { vm.step(program); vm.step(program); } catch (RuntimeException e) { + program.getResult().repository.close(); assertTrue(program.isStopped()); return; } + program.getResult().repository.close(); fail(); } @@ -1128,9 +1223,9 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); assertEquals(expectedLen, program.stack.toArray().length); - } @@ -1144,9 +1239,11 @@ public class VMTest { vm.step(program); vm.step(program); } catch (RuntimeException e) { + program.getResult().repository.close(); assertTrue(program.isStopped()); return; } + program.getResult().repository.close(); fail(); } @@ -1162,6 +1259,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @@ -1179,6 +1277,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); assertEquals(expectedLen, program.stack.toArray().length); } @@ -1194,6 +1293,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.memory.array())); } @@ -1212,6 +1312,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.memory.array())); } @@ -1233,6 +1334,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.memory.array())); } @@ -1253,6 +1355,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(expected, Hex.toHexString(program.memory.array())); } @@ -1260,15 +1363,17 @@ public class VMTest { @Test // MSTORE OP public void testMSTORE_5(){ + VM vm = new VM(); + Program program = new Program(Hex.decode("61123454"), new ProgramInvokeMockImpl()); try { - VM vm = new VM(); - Program program = new Program(Hex.decode("61123454"), new ProgramInvokeMockImpl()); vm.step(program); vm.step(program); } catch (RuntimeException e) { + program.getResult().repository.close(); return; } + program.getResult().repository.close(); fail(); } @@ -1283,6 +1388,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(m_expected, Hex.toHexString(program.memory.array())); assertEquals(s_expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @@ -1300,6 +1406,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(m_expected, Hex.toHexString(program.memory.array()).toUpperCase()); assertEquals(s_expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @@ -1317,9 +1424,9 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(m_expected, Hex.toHexString(program.memory.array())); assertEquals(s_expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); - } @Test // MLOAD OP @@ -1337,6 +1444,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(m_expected, Hex.toHexString(program.memory.array())); assertEquals(s_expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @@ -1356,6 +1464,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(m_expected, Hex.toHexString(program.memory.array())); assertEquals(s_expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @@ -1370,8 +1479,10 @@ public class VMTest { vm.step(program); } catch (RuntimeException e) { assertTrue(program.isStopped()); + program.getResult().repository.close(); return; } + program.getResult().repository.close(); fail(); } @@ -1387,6 +1498,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(m_expected, Hex.toHexString(program.memory.array())); } @@ -1402,6 +1514,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(m_expected, Hex.toHexString(program.memory.array())); } @@ -1417,6 +1530,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(m_expected, Hex.toHexString(program.memory.array())); } @@ -1429,11 +1543,12 @@ public class VMTest { vm.step(program); vm.step(program); } catch (RuntimeException e) { + program.getResult().repository.close(); assertTrue(program.isStopped()); return; } + program.getResult().repository.close(); fail(); - } @@ -1441,7 +1556,9 @@ public class VMTest { public void testSSTORE_1(){ VM vm = new VM(); - Program program = new Program(Hex.decode("602260AA57"), new ProgramInvokeMockImpl()); + ProgramInvokeMockImpl invoke = new ProgramInvokeMockImpl(); + + Program program = new Program(Hex.decode("602260AA57"), invoke); String s_expected_key = "00000000000000000000000000000000000000000000000000000000000000AA"; String s_expected_val = "0000000000000000000000000000000000000000000000000000000000000022"; @@ -1449,21 +1566,20 @@ public class VMTest { vm.step(program); vm.step(program); - DataWord key = program.storage.keySet().iterator().next(); - assertEquals(s_expected_key, - Hex.toHexString(key.getData()).toUpperCase()); - - DataWord val = program.storage.get(key); - assertEquals(s_expected_val, - Hex.toHexString(val.getData()).toUpperCase()); + DataWord key = new DataWord(Hex.decode(s_expected_key)); + DataWord val = program.result.getRepository().getStorageValue(invoke.getOwnerAddress().getNoLeadZeroesData(), key); + program.getResult().repository.close(); + assertEquals(s_expected_val, Hex.toHexString(val.getData()).toUpperCase()); } @Test // SSTORE OP public void testSSTORE_2(){ VM vm = new VM(); - Program program = new Program(Hex.decode("602260AA57602260BB57"), new ProgramInvokeMockImpl()); + ProgramInvokeMockImpl invoke = new ProgramInvokeMockImpl(); + + Program program = new Program(Hex.decode("602260AA57602260BB57"), invoke); String s_expected_key = "00000000000000000000000000000000000000000000000000000000000000BB"; String s_expected_val = "0000000000000000000000000000000000000000000000000000000000000022"; @@ -1474,29 +1590,29 @@ public class VMTest { vm.step(program); vm.step(program); - DataWord key = program.storage.keySet().iterator().next(); - assertEquals(s_expected_key, - Hex.toHexString(key.getData()).toUpperCase()); - - DataWord val = program.storage.get(key); - assertEquals(s_expected_val, - Hex.toHexString(val.getData()).toUpperCase()); + Repository repository = program.result.getRepository(); + DataWord key = new DataWord(Hex.decode(s_expected_key)); + DataWord val = repository.getStorageValue(invoke.getOwnerAddress().getNoLeadZeroesData(), key); + program.getResult().repository.close(); + assertEquals(s_expected_val, Hex.toHexString(val.getData()).toUpperCase()); } @Test // SSTORE OP public void testSSTORE_3(){ + VM vm = new VM(); + Program program = new Program(Hex.decode("602257"), new ProgramInvokeMockImpl()); try { - VM vm = new VM(); - Program program = new Program(Hex.decode("602257"), new ProgramInvokeMockImpl()); vm.step(program); vm.step(program); } catch (RuntimeException e) { + program.getResult().repository.close(); return; } + program.getResult().repository.close(); fail(); } @@ -1511,6 +1627,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(s_expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @@ -1527,6 +1644,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(s_expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @@ -1546,6 +1664,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(s_expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @@ -1553,14 +1672,16 @@ public class VMTest { @Test // SLOAD OP public void testSLOAD_4(){ + VM vm = new VM(); + Program program = new Program(Hex.decode("56"), new ProgramInvokeMockImpl()); try { - VM vm = new VM(); - Program program = new Program(Hex.decode("56"), new ProgramInvokeMockImpl()); vm.step(program); } catch (RuntimeException e) { + program.getResult().repository.close(); return; } + program.getResult().repository.close(); fail(); } @@ -1573,6 +1694,7 @@ public class VMTest { vm.step(program); + program.getResult().repository.close(); assertEquals(s_expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @@ -1591,6 +1713,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(s_expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @@ -1608,6 +1731,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(s_expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @@ -1620,9 +1744,11 @@ public class VMTest { vm.step(program); vm.step(program); } catch (RuntimeException e) { + program.getResult().repository.close(); assertTrue(program.isStopped()); return; } + program.getResult().repository.close(); fail(); } @@ -1639,6 +1765,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(s_expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @@ -1660,6 +1787,7 @@ public class VMTest { DataWord item1 = program.stack.pop(); DataWord item2 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); assertEquals(s_expected_2, Hex.toHexString(item2.data).toUpperCase()); } @@ -1673,9 +1801,11 @@ public class VMTest { vm.step(program); vm.step(program); } catch (RuntimeException e) { + program.getResult().repository.close(); assertTrue(program.isStopped()); return; } + program.getResult().repository.close(); fail(); } @@ -1689,8 +1819,10 @@ public class VMTest { vm.step(program); vm.step(program); } catch (RuntimeException e) { + program.getResult().repository.close(); return; } + program.getResult().repository.close(); fail(); } @@ -1706,6 +1838,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -1721,6 +1854,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -1736,6 +1870,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -1748,11 +1883,12 @@ public class VMTest { vm.step(program); vm.step(program); } catch (RuntimeException e) { + program.getResult().repository.close(); assertTrue(program.isStopped()); return; } + program.getResult().repository.close(); fail(); - } @Test // MULL OP @@ -1767,6 +1903,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -1782,6 +1919,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -1797,6 +1935,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -1809,9 +1948,11 @@ public class VMTest { vm.step(program); vm.step(program); } catch (RuntimeException e) { + program.getResult().repository.close(); assertTrue(program.isStopped()); return; } + program.getResult().repository.close(); fail(); } @@ -1828,6 +1969,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -1843,6 +1985,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -1859,6 +2002,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -1874,6 +2018,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -1890,23 +2035,25 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @Test // DIV OP public void testDIV_6(){ + VM vm = new VM(); + Program program = new Program(Hex.decode("600704"), new ProgramInvokeMockImpl()); try { - VM vm = new VM(); - Program program = new Program(Hex.decode("600704"), new ProgramInvokeMockImpl()); vm.step(program); vm.step(program); } catch (RuntimeException e) { + program.getResult().repository.close(); return; } + program.getResult().repository.close(); fail(); - } @@ -1922,6 +2069,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -1937,6 +2085,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -1952,6 +2101,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -1966,9 +2116,11 @@ public class VMTest { vm.step(program); vm.step(program); } catch (RuntimeException e) { + program.getResult().repository.close(); assertTrue(program.isStopped()); return; } + program.getResult().repository.close(); fail(); } @@ -1986,6 +2138,7 @@ public class VMTest { DataWord item1 = program.stack.pop(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); + program.getResult().repository.close(); } @Test // SUB OP @@ -2000,6 +2153,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -2015,6 +2169,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -2027,11 +2182,12 @@ public class VMTest { vm.step(program); vm.step(program); } catch (RuntimeException e) { + program.getResult().repository.close(); assertTrue(program.isStopped()); return; } + program.getResult().repository.close(); fail(); - } @Test // MSIZE OP @@ -2044,6 +2200,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -2060,6 +2217,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -2077,6 +2235,7 @@ public class VMTest { vm.step(program); ++i; } + program.getResult().repository.close(); assertEquals(expectedSteps, i); } @@ -2093,6 +2252,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -2108,6 +2268,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -2121,9 +2282,11 @@ public class VMTest { vm.step(program); vm.step(program); } catch (RuntimeException e) { + program.getResult().repository.close(); assertTrue(program.isStopped()); return; } + program.getResult().repository.close(); fail(); } @@ -2141,6 +2304,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(program.getResult().getHReturn().array()).toUpperCase()); assertTrue(program.stopped); } @@ -2160,6 +2324,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(program.getResult().getHReturn().array()).toUpperCase()); assertTrue(program.stopped); } @@ -2180,6 +2345,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(program.getResult().getHReturn().array()).toUpperCase()); assertTrue(program.stopped); } @@ -2201,6 +2367,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(program.getResult().getHReturn().array()).toUpperCase()); assertTrue(program.stopped); } @@ -2219,6 +2386,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(m_expected_1, Hex.toHexString(program.memory.array()).toUpperCase()); } @@ -2236,6 +2404,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(m_expected_1, Hex.toHexString(program.memory.array()).toUpperCase()); } @@ -2252,6 +2421,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertTrue(program.isStopped()); } @@ -2268,6 +2438,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertTrue(program.isStopped()); } @@ -2284,9 +2455,11 @@ public class VMTest { vm.step(program); vm.step(program); } catch (RuntimeException e) { + program.getResult().repository.close(); assertTrue(program.isStopped()); return; } + program.getResult().repository.close(); fail(); } @@ -2303,6 +2476,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -2319,6 +2493,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -2336,6 +2511,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -2352,6 +2528,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -2369,6 +2546,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -2386,6 +2564,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -2402,6 +2581,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -2416,9 +2596,11 @@ public class VMTest { try { vm.step(program); } catch (RuntimeException e) { + program.getResult().repository.close(); assertTrue(program.isStopped()); return; } + program.getResult().repository.close(); fail(); } @@ -2437,6 +2619,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(m_expected, Hex.toHexString(program.memory.array()).toUpperCase()); } @@ -2455,6 +2638,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(m_expected, Hex.toHexString(program.memory.array()).toUpperCase()); } @@ -2474,6 +2658,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(m_expected, Hex.toHexString(program.memory.array()).toUpperCase()); } @@ -2494,6 +2679,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(m_expected, Hex.toHexString(program.memory.array()).toUpperCase()); } @@ -2513,6 +2699,7 @@ public class VMTest { vm.step(program); vm.step(program); + program.getResult().repository.close(); assertEquals(m_expected, Hex.toHexString(program.memory.array()).toUpperCase()); } @@ -2530,9 +2717,11 @@ public class VMTest { vm.step(program); vm.step(program); } catch (RuntimeException e) { + program.getResult().repository.close(); assertTrue(program.stopped); return; } + program.getResult().repository.close(); fail(); } @@ -2549,6 +2738,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -2565,6 +2755,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -2581,6 +2772,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -2597,6 +2789,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -2612,6 +2805,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -2633,6 +2827,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -2654,6 +2849,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -2672,9 +2868,11 @@ public class VMTest { vm.step(program); vm.step(program); } catch (RuntimeException e) { + program.getResult().repository.close(); assertTrue(program.isStopped()); return; } + program.getResult().repository.close(); fail(); } @@ -2690,6 +2888,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -2704,6 +2903,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -2718,6 +2918,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -2733,9 +2934,11 @@ public class VMTest { vm.step(program); vm.step(program); } catch (RuntimeException e) { + program.getResult().repository.close(); assertTrue(program.isStopped()); return; } + program.getResult().repository.close(); fail(); } @@ -2750,6 +2953,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -2766,6 +2970,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -2783,6 +2988,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -2796,9 +3002,11 @@ public class VMTest { vm.step(program); vm.step(program); } catch (Exception e) { + program.getResult().repository.close(); assertTrue(program.isStopped()); return; } + program.getResult().repository.close(); fail(); } @@ -2814,6 +3022,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -2830,6 +3039,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -2845,6 +3055,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -2861,6 +3072,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -2876,6 +3088,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -2892,6 +3105,7 @@ public class VMTest { vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -2902,11 +3116,12 @@ public class VMTest { Program program = new Program(Hex.decode("5C"), createProgramInvoke_1()); - String s_expected_1 = "00000000000000000000000000000000000000000000000000000000000003E8"; + String s_expected_1 = "00000000000000000000000000000000000000000000000000000000000F423F"; vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -2917,12 +3132,12 @@ public class VMTest { Program program = new Program(Hex.decode("45"), createProgramInvoke_1()); - String s_expected_1 = "00000000000000000000000000000000000000000000000000000000000EC64D"; - + String s_expected_1 = "00000000000000000000000000000000000000000000000000000000000F4240"; vm.step(program); DataWord item1 = program.stack.pop(); + program.getResult().repository.close(); assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase()); } @@ -2932,15 +3147,21 @@ public class VMTest { public ProgramInvoke createProgramInvoke_1(){ + String ownerAddress = "77045E71A7A2C50903D88E564CD72FAB11E82051"; + byte[] address = Hex.decode(ownerAddress); byte[] msgData = Hex.decode("00000000000000000000000000000000000000000000000000000000000000A1" + "00000000000000000000000000000000000000000000000000000000000000B1"); ProgramInvokeMockImpl pi = new ProgramInvokeMockImpl(msgData); + pi.setOwnerAddress(ownerAddress); + + pi.getRepository().createAccount(address); return pi; } + }