Fix memory allocation and add unit tests
This commit is contained in:
parent
c51e56831a
commit
561d1dd296
|
@ -1,6 +1,7 @@
|
|||
package org.ethereum.core;
|
||||
|
||||
import org.ethereum.db.Repository;
|
||||
import org.ethereum.db.RepositoryImpl;
|
||||
import org.ethereum.facade.Blockchain;
|
||||
import org.ethereum.listener.EthereumListener;
|
||||
import org.ethereum.manager.WorldManager;
|
||||
import org.ethereum.net.BlockQueue;
|
||||
|
@ -50,7 +51,7 @@ import static org.ethereum.core.Denomination.SZABO;
|
|||
* Created on: 20/05/2014 10:44
|
||||
*
|
||||
*/
|
||||
public class Blockchain implements org.ethereum.facade.Blockchain{
|
||||
public class BlockchainImpl implements Blockchain {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger("blockchain");
|
||||
private static final Logger stateLogger = LoggerFactory.getLogger("state");
|
||||
|
@ -58,7 +59,7 @@ public class Blockchain implements org.ethereum.facade.Blockchain{
|
|||
// to avoid using minGasPrice=0 from Genesis for the wallet
|
||||
private static final long INITIAL_MIN_GAS_PRICE = 10 * SZABO.longValue();
|
||||
|
||||
private Repository repository;
|
||||
private RepositoryImpl repository;
|
||||
private Block lastBlock;
|
||||
|
||||
// keep the index of the chain for
|
||||
|
@ -67,7 +68,7 @@ public class Blockchain implements org.ethereum.facade.Blockchain{
|
|||
|
||||
private final BlockQueue blockQueue = new BlockQueue();
|
||||
|
||||
public Blockchain(Repository repository) {
|
||||
public BlockchainImpl(RepositoryImpl repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
|
@ -324,7 +325,7 @@ public class Blockchain implements org.ethereum.facade.Blockchain{
|
|||
if (isContractCreation || code != null) {
|
||||
|
||||
// START TRACKING FOR REVERT CHANGES OPTION
|
||||
Repository trackRepository = repository.getTrack();
|
||||
RepositoryImpl trackRepository = repository.getTrack();
|
||||
trackRepository.startTracking();
|
||||
try {
|
||||
|
||||
|
@ -385,7 +386,7 @@ public class Blockchain implements org.ethereum.facade.Blockchain{
|
|||
* @param contractAddress
|
||||
*/
|
||||
private void applyProgramResult(ProgramResult result, BigInteger gasDebit,
|
||||
Repository repository, byte[] senderAddress,
|
||||
RepositoryImpl repository, byte[] senderAddress,
|
||||
byte[] contractAddress, byte[] coinbase, boolean initResults) {
|
||||
|
||||
if (result.getException() != null
|
|
@ -3,9 +3,10 @@ package org.ethereum.db;
|
|||
import org.codehaus.plexus.util.FileUtils;
|
||||
import org.ethereum.core.AccountState;
|
||||
import org.ethereum.core.Block;
|
||||
import org.ethereum.core.Blockchain;
|
||||
import org.ethereum.core.BlockchainImpl;
|
||||
import org.ethereum.core.Genesis;
|
||||
import org.ethereum.crypto.HashUtil;
|
||||
import org.ethereum.facade.Repository;
|
||||
import org.ethereum.json.EtherObjectMapper;
|
||||
import org.ethereum.json.JSONHelper;
|
||||
import org.ethereum.listener.EthereumListener;
|
||||
|
@ -18,6 +19,7 @@ import org.iq80.leveldb.DBIterator;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
|
||||
|
@ -51,7 +53,7 @@ import static org.ethereum.config.SystemProperties.CONFIG;
|
|||
* @author: Roman Mandeleil
|
||||
* Created on: 23/06/2014 23:01
|
||||
*/
|
||||
public class Repository implements org.ethereum.facade.Repository{
|
||||
public class RepositoryImpl implements Repository {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger("repository");
|
||||
|
||||
|
@ -72,7 +74,7 @@ public class Repository implements org.ethereum.facade.Repository{
|
|||
*
|
||||
* @See loadBlockchain() to update the stateRoot
|
||||
*/
|
||||
public Repository() {
|
||||
public RepositoryImpl() {
|
||||
chainDB = new DatabaseImpl("blockchain");
|
||||
detailsDB = new DatabaseImpl("details");
|
||||
contractDetailsDB = new TrackDatabase(detailsDB);
|
||||
|
@ -81,15 +83,15 @@ public class Repository implements org.ethereum.facade.Repository{
|
|||
accountStateDB = new TrackTrie(worldState);
|
||||
}
|
||||
|
||||
private Repository(TrackTrie accountStateDB, TrackDatabase contractDetailsDB) {
|
||||
private RepositoryImpl(TrackTrie accountStateDB, TrackDatabase contractDetailsDB) {
|
||||
this.accountStateDB = accountStateDB;
|
||||
this.contractDetailsDB = contractDetailsDB;
|
||||
}
|
||||
|
||||
public Repository getTrack() {
|
||||
public RepositoryImpl getTrack() {
|
||||
TrackTrie trackState = new TrackTrie(accountStateDB);
|
||||
TrackDatabase trackDetails = new TrackDatabase(contractDetailsDB);
|
||||
return new Repository (trackState, trackDetails);
|
||||
return new RepositoryImpl (trackState, trackDetails);
|
||||
}
|
||||
|
||||
public void startTracking() {
|
||||
|
@ -121,8 +123,8 @@ public class Repository implements org.ethereum.facade.Repository{
|
|||
this.worldState.sync();
|
||||
}
|
||||
|
||||
public Blockchain loadBlockchain() {
|
||||
Blockchain blockchain = WorldManager.getInstance().getBlockchain();
|
||||
public BlockchainImpl loadBlockchain() {
|
||||
BlockchainImpl blockchain = WorldManager.getInstance().getBlockchain();
|
||||
DBIterator iterator = chainDB.iterator();
|
||||
try {
|
||||
if (!iterator.hasNext()) {
|
|
@ -7,7 +7,7 @@ import java.util.concurrent.Future;
|
|||
|
||||
import org.ethereum.core.Transaction;
|
||||
import org.ethereum.core.Wallet;
|
||||
import org.ethereum.db.Repository;
|
||||
import org.ethereum.db.RepositoryImpl;
|
||||
import org.ethereum.listener.EthereumListener;
|
||||
import org.ethereum.manager.WorldManager;
|
||||
import org.ethereum.net.client.ClientPeer;
|
||||
|
@ -195,7 +195,7 @@ public class EthereumImpl implements Ethereum {
|
|||
|
||||
|
||||
@Override
|
||||
public Repository getRepository(){
|
||||
public RepositoryImpl getRepository(){
|
||||
return WorldManager.getInstance().getRepository();
|
||||
}
|
||||
|
||||
|
|
|
@ -3,8 +3,6 @@ package org.ethereum.facade;
|
|||
import org.ethereum.core.AccountState;
|
||||
import org.ethereum.db.ContractDetails;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* www.ethereumJ.com
|
||||
*
|
||||
|
@ -16,5 +14,4 @@ public interface Repository {
|
|||
|
||||
public AccountState getAccountState(byte[] addr);
|
||||
public ContractDetails getContractDetails(byte[] addr);
|
||||
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import org.ethereum.core.AccountState;
|
|||
import org.ethereum.core.Block;
|
||||
import org.ethereum.db.ByteArrayWrapper;
|
||||
import org.ethereum.db.ContractDetails;
|
||||
import org.ethereum.db.Repository;
|
||||
import org.ethereum.db.RepositoryImpl;
|
||||
import org.ethereum.util.ByteUtil;
|
||||
import org.ethereum.vm.DataWord;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
@ -67,7 +67,7 @@ public class JSONHelper {
|
|||
|
||||
public static void dumpBlock(ObjectNode blockNode, Block block,
|
||||
long gasUsed, byte[] state, List<ByteArrayWrapper> keys,
|
||||
Repository repository) {
|
||||
RepositoryImpl repository) {
|
||||
|
||||
blockNode.put("coinbase", Hex.toHexString(block.getCoinbase()));
|
||||
blockNode.put("difficulty", new BigInteger(1, block.calcDifficulty()).toString());
|
||||
|
|
|
@ -2,7 +2,7 @@ package org.ethereum.jsontestsuite;
|
|||
|
||||
import org.ethereum.db.ByteArrayWrapper;
|
||||
import org.ethereum.db.ContractDetails;
|
||||
import org.ethereum.db.Repository;
|
||||
import org.ethereum.db.RepositoryImpl;
|
||||
import org.ethereum.util.ByteUtil;
|
||||
import org.ethereum.vm.*;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -46,7 +46,7 @@ public class TestRunner {
|
|||
|
||||
List<String> results = new ArrayList<>();
|
||||
|
||||
Repository repository = new Repository();
|
||||
RepositoryImpl repository = new RepositoryImpl();
|
||||
|
||||
/* 1. Store pre-exist accounts - Pre */
|
||||
for (ByteArrayWrapper key : testCase.getPre().keySet()){
|
||||
|
|
|
@ -2,17 +2,14 @@ package org.ethereum.manager;
|
|||
|
||||
import static org.ethereum.config.SystemProperties.CONFIG;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.*;
|
||||
|
||||
import org.ethereum.core.AccountState;
|
||||
import org.ethereum.core.Blockchain;
|
||||
import org.ethereum.core.BlockchainImpl;
|
||||
import org.ethereum.core.Wallet;
|
||||
import org.ethereum.crypto.ECKey;
|
||||
import org.ethereum.crypto.HashUtil;
|
||||
import org.ethereum.db.Repository;
|
||||
import org.ethereum.db.RepositoryImpl;
|
||||
import org.ethereum.listener.EthereumListener;
|
||||
import org.ethereum.net.client.ClientPeer;
|
||||
import org.ethereum.net.client.PeerData;
|
||||
|
@ -28,8 +25,8 @@ import org.ethereum.net.peerdiscovery.PeerDiscovery;
|
|||
*/
|
||||
public class WorldManager {
|
||||
|
||||
private Blockchain blockchain;
|
||||
private Repository repository;
|
||||
private BlockchainImpl blockchain;
|
||||
private RepositoryImpl repository;
|
||||
private Wallet wallet;
|
||||
|
||||
private PeerDiscovery peerDiscovery;
|
||||
|
@ -48,8 +45,8 @@ public class WorldManager {
|
|||
}
|
||||
|
||||
private WorldManager() {
|
||||
this.repository = new Repository();
|
||||
this.blockchain = new Blockchain(repository);
|
||||
this.repository = new RepositoryImpl();
|
||||
this.blockchain = new BlockchainImpl(repository);
|
||||
|
||||
// Initialize PeerData
|
||||
List<PeerData> peerDataList = parsePeerDiscoveryIpList(CONFIG.peerDiscoveryIPList());
|
||||
|
@ -60,17 +57,15 @@ public class WorldManager {
|
|||
}
|
||||
|
||||
// used for testing
|
||||
public void reset(){
|
||||
|
||||
this.repository = new Repository();
|
||||
this.blockchain = new Blockchain(repository);
|
||||
public void reset() {
|
||||
this.repository = new RepositoryImpl();
|
||||
this.blockchain = new BlockchainImpl(repository);
|
||||
}
|
||||
|
||||
public void init(){
|
||||
this.wallet = new Wallet();
|
||||
public void init() {
|
||||
|
||||
this.wallet = new Wallet();
|
||||
byte[] cowAddr = HashUtil.sha3("cow".getBytes());
|
||||
ECKey key = ECKey.fromPrivate(cowAddr);
|
||||
wallet.importKey(cowAddr);
|
||||
|
||||
// AccountState state = wallet.getAccountState(key.getAddress());
|
||||
|
@ -79,20 +74,19 @@ public class WorldManager {
|
|||
String secret = CONFIG.coinbaseSecret();
|
||||
byte[] cbAddr = HashUtil.sha3(secret.getBytes());
|
||||
wallet.importKey(cbAddr);
|
||||
|
||||
}
|
||||
|
||||
public static WorldManager getInstance() {
|
||||
return WorldManagerHolder.instance;
|
||||
}
|
||||
|
||||
public void addListener(EthereumListener listener){
|
||||
public void addListener(EthereumListener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
public void addPeers(final Set<PeerData> newPeers) {
|
||||
|
||||
synchronized (peers){
|
||||
synchronized (peers) {
|
||||
for (final PeerData peer : newPeers) {
|
||||
if (peerDiscovery.isStarted() && !peers.contains(peer)) {
|
||||
peerDiscovery.addNewPeerData(peer);
|
||||
|
@ -149,11 +143,11 @@ public class WorldManager {
|
|||
this.wallet = wallet;
|
||||
}
|
||||
|
||||
public Repository getRepository() {
|
||||
public RepositoryImpl getRepository() {
|
||||
return repository;
|
||||
}
|
||||
|
||||
public Blockchain getBlockchain() {
|
||||
public BlockchainImpl getBlockchain() {
|
||||
return blockchain;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import org.spongycastle.util.Arrays;
|
|||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.math.BigDecimal;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
|
@ -41,15 +42,12 @@ public class DataWord implements Comparable<DataWord> {
|
|||
}
|
||||
|
||||
public DataWord(byte[] data) {
|
||||
|
||||
if (data == null) {
|
||||
this.data = new byte[] {};
|
||||
return;
|
||||
}
|
||||
|
||||
if (data.length > 32)
|
||||
throw new RuntimeException("Data word can't exit 32 bytes: " + data);
|
||||
System.arraycopy(data, 0, this.data, 32 - data.length, data.length);
|
||||
if (data == null)
|
||||
this.data = ByteUtil.EMPTY_BYTE_ARRAY;
|
||||
else if (data.length <= 32)
|
||||
System.arraycopy(data, 0, this.data, 32 - data.length, data.length);
|
||||
else
|
||||
throw new RuntimeException("Data word can't exit 32 bytes: " + data);
|
||||
}
|
||||
|
||||
public byte[] getData() {
|
||||
|
@ -67,12 +65,32 @@ public class DataWord implements Comparable<DataWord> {
|
|||
return new BigInteger(1, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts this DataWord to an int, checking for lost information.
|
||||
* If this DataWord is out of the possible range for an int result
|
||||
* then an ArithmeticException is thrown.
|
||||
*
|
||||
* @return this DataWord converted to an int.
|
||||
* @throws ArithmeticException - if this will not fit in an int.
|
||||
*/
|
||||
public int intValue() {
|
||||
return new BigInteger(1, data).intValue();
|
||||
// FIXME: Disabled for POC5
|
||||
// BigDecimal tmpValue = new BigDecimal(this.value());
|
||||
// return tmpValue.intValueExact();
|
||||
return this.value().intValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts this DataWord to a long, checking for lost information.
|
||||
* If this DataWord is out of the possible range for a long result
|
||||
* then an ArithmeticException is thrown.
|
||||
*
|
||||
* @return this DataWord converted to a long.
|
||||
* @throws ArithmeticException - if this will not fit in a long.
|
||||
*/
|
||||
public long longValue() {
|
||||
return new BigInteger(1, data).longValue();
|
||||
BigDecimal tmpValue = new BigDecimal(this.value());
|
||||
return tmpValue.longValueExact();
|
||||
}
|
||||
|
||||
public BigInteger sValue() {
|
||||
|
@ -219,7 +237,7 @@ public class DataWord implements Comparable<DataWord> {
|
|||
// TODO: improve with no BigInteger
|
||||
public void exp(DataWord word) {
|
||||
|
||||
BigInteger result = value().pow(word.value().intValue());
|
||||
BigInteger result = value().pow(word.intValue());
|
||||
byte[] bytes = result.toByteArray();
|
||||
|
||||
ByteBuffer data = ByteBuffer.allocate(32);
|
||||
|
@ -300,4 +318,4 @@ public class DataWord implements Comparable<DataWord> {
|
|||
data, 0, data.length,
|
||||
o.getData(), 0, o.getData().length);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@ package org.ethereum.vm;
|
|||
|
||||
import org.ethereum.crypto.HashUtil;
|
||||
import org.ethereum.db.ContractDetails;
|
||||
import org.ethereum.db.Repository;
|
||||
import org.ethereum.db.RepositoryImpl;
|
||||
import org.ethereum.util.ByteUtil;
|
||||
import org.ethereum.util.Utils;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -43,16 +43,17 @@ public class Program {
|
|||
ProgramInvoke invokeData;
|
||||
|
||||
public Program(byte[] ops, ProgramInvoke invokeData) {
|
||||
|
||||
this.invokeHash = invokeData.hashCode();
|
||||
result.setRepository(invokeData.getRepository());
|
||||
|
||||
if (ops == null) ops = new byte[0]; //throw new RuntimeException("program can not run with ops: null");
|
||||
|
||||
this.invokeData = invokeData;
|
||||
|
||||
if (ops == null) ops = ByteUtil.EMPTY_BYTE_ARRAY;
|
||||
this.ops = ops;
|
||||
this.programAddress = invokeData.getOwnerAddress();
|
||||
}
|
||||
|
||||
if (invokeData != null) {
|
||||
this.invokeData = invokeData;
|
||||
this.programAddress = invokeData.getOwnerAddress();
|
||||
this.invokeHash = invokeData.hashCode();
|
||||
this.result.setRepository(invokeData.getRepository());
|
||||
}
|
||||
}
|
||||
|
||||
public byte getCurrentOp() {
|
||||
if(ops.length == 0)
|
||||
|
@ -93,7 +94,7 @@ public class Program {
|
|||
|
||||
public void setPC(DataWord pc) {
|
||||
|
||||
this.pc = pc.value().intValue();
|
||||
this.pc = pc.intValue();
|
||||
|
||||
if (this.pc == ops.length) {
|
||||
stop();
|
||||
|
@ -162,71 +163,79 @@ public class Program {
|
|||
}
|
||||
|
||||
public void memorySave(DataWord addrB, DataWord value) {
|
||||
memorySave(addrB.getData(), value.getData());
|
||||
memorySave(addrB.intValue(), value.getData());
|
||||
}
|
||||
|
||||
public void memorySave(byte[] addr, byte[] value) {
|
||||
|
||||
int address = new BigInteger(1, addr).intValue();
|
||||
allocateMemory(address, value);
|
||||
System.arraycopy(value, 0, memory.array(), address, value.length);
|
||||
public void memorySave(int addr, byte[] value) {
|
||||
memorySave(addr, value.length, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates a piece of memory and stores value at given offset address
|
||||
*
|
||||
* @param addr is the offset address
|
||||
* @param allocSize size of memory needed to write
|
||||
* @param value the data to write to memory
|
||||
*/
|
||||
public void memorySave(int addr, int allocSize, byte[] value) {
|
||||
|
||||
allocateMemory(addr, allocSize);
|
||||
System.arraycopy(value, 0, memory.array(), addr, value.length);
|
||||
}
|
||||
|
||||
public DataWord memoryLoad(DataWord addr) {
|
||||
return memoryLoad(addr.intValue());
|
||||
}
|
||||
|
||||
public DataWord memoryLoad(int address) {
|
||||
|
||||
int address = new BigInteger(1, addr.getData()).intValue();
|
||||
allocateMemory(address, DataWord.ZERO.getData());
|
||||
allocateMemory(address, DataWord.ZERO.getData().length);
|
||||
|
||||
byte[] data = new byte[32];
|
||||
System.arraycopy(memory.array(), address, data , 0 ,32);
|
||||
DataWord newMem = new DataWord();
|
||||
System.arraycopy(memory.array(), address, newMem.getData(), 0, newMem.getData().length);
|
||||
|
||||
return new DataWord(data);
|
||||
return newMem;
|
||||
}
|
||||
|
||||
public ByteBuffer memoryChunk(DataWord offsetData, DataWord sizeData) {
|
||||
return memoryChunk(offsetData.intValue(), sizeData.intValue());
|
||||
}
|
||||
|
||||
int offset = offsetData.intValue();
|
||||
int size = sizeData.intValue();
|
||||
byte[] chunk = new byte[size];
|
||||
allocateMemory(offset, new byte[size]);
|
||||
/**
|
||||
* Returns a piece of memory from a given offset and specified size
|
||||
* If the offset + size exceed the current memory-size,
|
||||
* the remainder will be filled with empty bytes.
|
||||
*
|
||||
* @param offset byte address in memory
|
||||
* @param size the amount of bytes to return
|
||||
* @return ByteBuffer containing the chunk of memory data
|
||||
*/
|
||||
public ByteBuffer memoryChunk(int offset, int size) {
|
||||
|
||||
if (memory != null) {
|
||||
if (memory.limit() < offset + size) size = memory.limit() - offset;
|
||||
System.arraycopy(memory.array(), offset, chunk, 0, size);
|
||||
}
|
||||
allocateMemory(offset, size);
|
||||
byte[] chunk;
|
||||
if (memory != null)
|
||||
chunk = Arrays.copyOfRange(memory.array(), offset, offset+size);
|
||||
else
|
||||
chunk = new byte[size];
|
||||
return ByteBuffer.wrap(chunk);
|
||||
}
|
||||
|
||||
private void allocateMemory(int address, byte[] value) {
|
||||
/**
|
||||
* Allocates extra memory in the program for
|
||||
* a specified size, calculated from a given offset
|
||||
*
|
||||
* @param offset the memory address offset
|
||||
* @param size the number of bytes to allocate
|
||||
*/
|
||||
protected void allocateMemory(int offset, int size) {
|
||||
|
||||
int memSize = 0;
|
||||
if (memory != null) memSize = memory.limit();
|
||||
|
||||
// check if you need to allocate
|
||||
if (memSize < (address + value.length)) {
|
||||
|
||||
long overlap = memSize - address;
|
||||
|
||||
int sizeToAllocate = 0;
|
||||
if (memSize > address) {
|
||||
sizeToAllocate = memSize + value.length;
|
||||
} else {
|
||||
sizeToAllocate = memSize + (address - memSize) + value.length;
|
||||
}
|
||||
|
||||
if (overlap > 0) sizeToAllocate -= overlap;
|
||||
|
||||
// complete to 32
|
||||
sizeToAllocate = (sizeToAllocate % 32)==0 ? sizeToAllocate :
|
||||
sizeToAllocate + (32 - sizeToAllocate % 32);
|
||||
sizeToAllocate = (sizeToAllocate == 0)? 32: sizeToAllocate;
|
||||
|
||||
ByteBuffer tmpMem = ByteBuffer.allocate(sizeToAllocate);
|
||||
if (memory != null)
|
||||
System.arraycopy(memory.array(), 0, tmpMem.array(), 0, memory.limit());
|
||||
|
||||
memory = tmpMem;
|
||||
}
|
||||
int memSize = memory != null ? memory.limit(): 0;
|
||||
double newMemSize = Math.max(memSize, Math.ceil((double)(offset + size) / 32) * 32);
|
||||
ByteBuffer tmpMem = ByteBuffer.allocate((int)newMemSize);
|
||||
if (memory != null)
|
||||
tmpMem.put(memory.array(), 0, memory.limit());
|
||||
memory = tmpMem;
|
||||
}
|
||||
|
||||
public void suicide(DataWord obtainer) {
|
||||
|
@ -282,13 +291,13 @@ public class Program {
|
|||
result.getRepository().addBalance(senderAddress, endowment.negate());
|
||||
result.getRepository().addBalance(newAddress, endowment);
|
||||
|
||||
Repository trackRepository = result.getRepository().getTrack();
|
||||
trackRepository.startTracking();
|
||||
RepositoryImpl trackRepositoryImpl = result.getRepository().getTrack();
|
||||
trackRepositoryImpl.startTracking();
|
||||
|
||||
// [5] COOK THE INVOKE AND EXECUTE
|
||||
ProgramInvoke programInvoke =
|
||||
ProgramInvokeFactory.createProgramInvoke(this, new DataWord(newAddress), DataWord.ZERO,
|
||||
new DataWord(gas), BigInteger.ZERO, null, trackRepository, this.invokeData.getCallDeep() + 1);
|
||||
new DataWord(gas), BigInteger.ZERO, null, trackRepositoryImpl, this.invokeData.getCallDeep() + 1);
|
||||
|
||||
VM vm = new VM();
|
||||
Program program = new Program(programCode.array(), programInvoke);
|
||||
|
@ -300,18 +309,18 @@ public class Program {
|
|||
result.getException() instanceof Program.OutOfGasException) {
|
||||
logger.info("contract run halted by OutOfGas: new contract init ={}" , Hex.toHexString(newAddress));
|
||||
|
||||
trackRepository.rollback();
|
||||
trackRepositoryImpl.rollback();
|
||||
stackPushZero();
|
||||
return;
|
||||
}
|
||||
|
||||
// 4. CREATE THE CONTRACT OUT OF RETURN
|
||||
byte[] code = result.getHReturn().array();
|
||||
trackRepository.saveCode(newAddress, code);
|
||||
trackRepositoryImpl.saveCode(newAddress, code);
|
||||
|
||||
// IN SUCCESS PUSH THE ADDRESS INTO THE STACK
|
||||
stackPush(new DataWord(newAddress));
|
||||
trackRepository.commit();
|
||||
trackRepositoryImpl.commit();
|
||||
|
||||
// 5. REFUND THE REMAIN GAS
|
||||
long refundGas = gas - result.getGasUsed();
|
||||
|
@ -388,15 +397,15 @@ public class Program {
|
|||
// actual gas subtract
|
||||
this.spendGas(gas.intValue(), "internal call");
|
||||
|
||||
Repository trackRepository = result.getRepository().getTrack();
|
||||
trackRepository.startTracking();
|
||||
trackRepository.addBalance(toAddress, endowmentValue.value());
|
||||
RepositoryImpl trackRepositoryImpl = result.getRepository().getTrack();
|
||||
trackRepositoryImpl.startTracking();
|
||||
trackRepositoryImpl.addBalance(toAddress, endowmentValue.value());
|
||||
|
||||
ProgramInvoke programInvoke =
|
||||
ProgramInvokeFactory.createProgramInvoke(this, toAddressDW,
|
||||
endowmentValue, gas, result.getRepository().getBalance(toAddress),
|
||||
data.array(),
|
||||
trackRepository, this.invokeData.getCallDeep() + 1);
|
||||
trackRepositoryImpl, this.invokeData.getCallDeep() + 1);
|
||||
|
||||
ProgramResult result = null;
|
||||
|
||||
|
@ -413,7 +422,7 @@ public class Program {
|
|||
result.getException() instanceof Program.OutOfGasException) {
|
||||
logger.info("contract run halted by OutOfGas: contract={}" , Hex.toHexString(toAddress));
|
||||
|
||||
trackRepository.rollback();
|
||||
trackRepositoryImpl.rollback();
|
||||
stackPushZero();
|
||||
return;
|
||||
}
|
||||
|
@ -421,24 +430,20 @@ public class Program {
|
|||
// 3. APPLY RESULTS: result.getHReturn() into out_memory allocated
|
||||
if (result != null) {
|
||||
ByteBuffer buffer = result.getHReturn();
|
||||
if (buffer != null) {
|
||||
int retSize = buffer.array().length;
|
||||
int allocSize = outDataSize.intValue();
|
||||
int allocSize = outDataSize.intValue();
|
||||
if (buffer != null && allocSize > 0) {
|
||||
int retSize = buffer.limit();
|
||||
int offset = outDataOffs.intValue();
|
||||
if (retSize > allocSize) {
|
||||
byte[] outArray = Arrays.copyOf(buffer.array(), allocSize);
|
||||
this.memorySave(outArray, buffer.array());
|
||||
} else if (retSize == 0 || retSize == allocSize){
|
||||
this.memorySave(outDataOffs.getData(), buffer.array());
|
||||
this.memorySave(offset, buffer.array());
|
||||
} else {
|
||||
byte[] outArray = new byte[allocSize];
|
||||
System.arraycopy(buffer.array(), 0, outArray, 0, retSize);
|
||||
this.memorySave(outDataOffs.getData(), outArray);
|
||||
this.memorySave(offset, allocSize, buffer.array());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 4. THE FLAG OF SUCCESS IS ONE PUSHED INTO THE STACK
|
||||
trackRepository.commit();
|
||||
trackRepositoryImpl.commit();
|
||||
stackPushOne();
|
||||
|
||||
// 5. REFUND THE REMAIN GAS
|
||||
|
@ -702,4 +707,4 @@ public class Program {
|
|||
@SuppressWarnings("serial")
|
||||
public class OutOfGasException extends RuntimeException {
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
package org.ethereum.vm;
|
||||
|
||||
import org.ethereum.db.Repository;
|
||||
import org.ethereum.db.RepositoryImpl;
|
||||
|
||||
/**
|
||||
* www.ethereumJ.com
|
||||
|
@ -27,7 +27,7 @@ public interface ProgramInvoke {
|
|||
public DataWord getDifficulty();
|
||||
public DataWord getGaslimit();
|
||||
|
||||
public Repository getRepository();
|
||||
public RepositoryImpl getRepository();
|
||||
|
||||
public boolean byTransaction();
|
||||
boolean byTestingSuite();
|
||||
|
|
|
@ -2,7 +2,7 @@ package org.ethereum.vm;
|
|||
|
||||
import org.ethereum.core.Block;
|
||||
import org.ethereum.core.Transaction;
|
||||
import org.ethereum.db.Repository;
|
||||
import org.ethereum.db.RepositoryImpl;
|
||||
import org.ethereum.manager.WorldManager;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -21,7 +21,7 @@ public class ProgramInvokeFactory {
|
|||
private static Logger logger = LoggerFactory.getLogger("VM");
|
||||
|
||||
// Invocation by the wire tx
|
||||
public static ProgramInvoke createProgramInvoke(Transaction tx, Block block, Repository repository) {
|
||||
public static ProgramInvoke createProgramInvoke(Transaction tx, Block block, RepositoryImpl repository) {
|
||||
|
||||
// https://ethereum.etherpad.mozilla.org/26
|
||||
Block lastBlock = WorldManager.getInstance().getBlockchain().getLastBlock();
|
||||
|
@ -122,7 +122,7 @@ public class ProgramInvokeFactory {
|
|||
public static ProgramInvoke createProgramInvoke(Program program, DataWord toAddress,
|
||||
DataWord inValue, DataWord inGas,
|
||||
BigInteger balanceInt, byte[] dataIn,
|
||||
Repository repository, int callDeep) {
|
||||
RepositoryImpl repository, int callDeep) {
|
||||
|
||||
DataWord address = toAddress;
|
||||
DataWord origin = program.getOriginAddress();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package org.ethereum.vm;
|
||||
|
||||
import org.ethereum.db.Repository;
|
||||
import org.ethereum.db.RepositoryImpl;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Arrays;
|
||||
|
@ -26,7 +26,7 @@ public class ProgramInvokeImpl implements ProgramInvoke {
|
|||
|
||||
Map<DataWord, DataWord> storage;
|
||||
|
||||
private Repository repository;
|
||||
private RepositoryImpl repository;
|
||||
private boolean byTransaction = true;
|
||||
private boolean byTestingSuite = false;
|
||||
private int callDeep = 0;
|
||||
|
@ -34,7 +34,7 @@ public class ProgramInvokeImpl implements ProgramInvoke {
|
|||
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, Repository repository, int callDeep) {
|
||||
DataWord gaslimit, RepositoryImpl repository, int callDeep) {
|
||||
|
||||
// Transaction env
|
||||
this.address = address;
|
||||
|
@ -63,7 +63,7 @@ public class ProgramInvokeImpl implements ProgramInvoke {
|
|||
byte[] gasPrice, byte[] gas, byte[] callValue, byte[] msgData,
|
||||
byte[] lastHash, byte[] coinbase, long timestamp, long number, byte[] difficulty,
|
||||
long gaslimit,
|
||||
Repository repository, boolean byTestingSuite) {
|
||||
RepositoryImpl repository, boolean byTestingSuite) {
|
||||
this(address, origin, caller, balance, gasPrice, gas, callValue, msgData, lastHash, coinbase,
|
||||
timestamp, number, difficulty, gaslimit, repository);
|
||||
this.byTestingSuite = byTestingSuite;
|
||||
|
@ -74,7 +74,7 @@ public class ProgramInvokeImpl implements ProgramInvoke {
|
|||
byte[] gasPrice, byte[] gas, byte[] callValue, byte[] msgData,
|
||||
byte[] lastHash, byte[] coinbase, long timestamp, long number, byte[] difficulty,
|
||||
long gaslimit,
|
||||
Repository repository) {
|
||||
RepositoryImpl repository) {
|
||||
|
||||
// Transaction env
|
||||
this.address = new DataWord(address);
|
||||
|
@ -215,7 +215,7 @@ public class ProgramInvokeImpl implements ProgramInvoke {
|
|||
/* Storage */
|
||||
public Map<DataWord, DataWord> getStorage() { return storage; }
|
||||
|
||||
public Repository getRepository() {
|
||||
public RepositoryImpl getRepository() {
|
||||
return repository;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ package org.ethereum.vm;
|
|||
|
||||
import org.ethereum.crypto.ECKey;
|
||||
import org.ethereum.crypto.HashUtil;
|
||||
import org.ethereum.db.Repository;
|
||||
import org.ethereum.db.RepositoryImpl;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
/**
|
||||
|
@ -15,7 +15,7 @@ public class ProgramInvokeMockImpl implements ProgramInvoke {
|
|||
private byte[] msgData;
|
||||
|
||||
|
||||
private Repository repository = null;
|
||||
private RepositoryImpl repository = null;
|
||||
private String ownerAddress = "cd2a3d9f938e13cd947ec05abc7fe734df8dd826";
|
||||
|
||||
public ProgramInvokeMockImpl(byte[] msgDataRaw) {
|
||||
|
@ -24,7 +24,7 @@ public class ProgramInvokeMockImpl implements ProgramInvoke {
|
|||
}
|
||||
|
||||
public ProgramInvokeMockImpl() {
|
||||
this.repository = new Repository();
|
||||
this.repository = new RepositoryImpl();
|
||||
this.repository.createAccount(Hex.decode(ownerAddress));
|
||||
}
|
||||
|
||||
|
@ -179,11 +179,11 @@ public class ProgramInvokeMockImpl implements ProgramInvoke {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Repository getRepository() {
|
||||
public RepositoryImpl getRepository() {
|
||||
return this.repository;
|
||||
}
|
||||
|
||||
public void setRepository(Repository repository) {
|
||||
public void setRepository(RepositoryImpl repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package org.ethereum.vm;
|
||||
|
||||
import org.ethereum.db.Repository;
|
||||
import org.ethereum.db.RepositoryImpl;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
|
@ -18,7 +18,7 @@ public class ProgramResult {
|
|||
private RuntimeException exception;
|
||||
private List<DataWord> deleteAccounts;
|
||||
|
||||
private Repository repository = null;
|
||||
private RepositoryImpl repository = null;
|
||||
|
||||
/*
|
||||
* for testing runs ,
|
||||
|
@ -55,11 +55,11 @@ public class ProgramResult {
|
|||
this.exception = exception;
|
||||
}
|
||||
|
||||
public Repository getRepository() {
|
||||
public RepositoryImpl getRepository() {
|
||||
return repository;
|
||||
}
|
||||
|
||||
public void setRepository(Repository repository) {
|
||||
public void setRepository(RepositoryImpl repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
|
|
|
@ -144,8 +144,8 @@ public class VM {
|
|||
}
|
||||
callGas = callGasWord.longValue();
|
||||
// Casting to long (causing overflow) as workaround for PoC5 - should be removed for PoC6
|
||||
long x = stack.get(stack.size()-6).value().add(stack.get(stack.size()-7).value()).longValue();
|
||||
long y = stack.get(stack.size()-4).value().add(stack.get(stack.size()-5).value()).longValue();
|
||||
long x = stack.get(stack.size()-4).value().add(stack.get(stack.size()-5).value()).longValue(); // in offset+size
|
||||
long y = stack.get(stack.size()-6).value().add(stack.get(stack.size()-7).value()).longValue(); // out offset+size
|
||||
newMemSize = BigInteger.valueOf(Math.max(x, y));
|
||||
break;
|
||||
case CREATE:
|
||||
|
@ -157,6 +157,7 @@ public class VM {
|
|||
}
|
||||
program.spendGas(gasCost, op.name());
|
||||
|
||||
// Avoid overflows
|
||||
if(newMemSize.compareTo(MAX_GAS) == 1) {
|
||||
throw program.new OutOfGasException();
|
||||
}
|
||||
|
@ -422,7 +423,7 @@ public class VM {
|
|||
DataWord word2 = program.stackPop();
|
||||
DataWord result = null;
|
||||
if (word1.value().compareTo(_32_) == -1) {
|
||||
byte tmp = word2.getData()[word1.value().intValue()];
|
||||
byte tmp = word2.getData()[word1.intValue()];
|
||||
word2.and(DataWord.ZERO);
|
||||
word2.getData()[31] = tmp;
|
||||
result = word2;
|
||||
|
@ -535,7 +536,7 @@ public class VM {
|
|||
if (logger.isInfoEnabled())
|
||||
hint = "data: " + Hex.toHexString(msgData);
|
||||
|
||||
program.memorySave(memOffsetData.getData(), msgData);
|
||||
program.memorySave(memOffsetData.intValue(), msgData);
|
||||
program.step();
|
||||
} break;
|
||||
case CODESIZE:{
|
||||
|
@ -552,8 +553,8 @@ public class VM {
|
|||
DataWord codeOffsetData = program.stackPop();
|
||||
DataWord lengthData = program.stackPop();
|
||||
|
||||
int length = lengthData.value().intValue();
|
||||
int codeOffset = codeOffsetData.value().intValue();
|
||||
int length = lengthData.intValue();
|
||||
int codeOffset = codeOffsetData.intValue();
|
||||
|
||||
if (program.ops.length < length + codeOffset) {
|
||||
program.stop();
|
||||
|
@ -566,7 +567,7 @@ public class VM {
|
|||
if (logger.isInfoEnabled())
|
||||
hint = "code: " + Hex.toHexString(code);
|
||||
|
||||
program.memorySave(memOffsetData.getData(), code);
|
||||
program.memorySave(memOffsetData.intValue(), code);
|
||||
program.step();
|
||||
} break;
|
||||
case GASPRICE:{
|
||||
|
@ -678,7 +679,7 @@ public class VM {
|
|||
DataWord addr = program.stackPop();
|
||||
DataWord value = program.stackPop();
|
||||
byte[] byteVal = {value.getData()[31]};
|
||||
program.memorySave(addr.getData(), byteVal);
|
||||
program.memorySave(addr.intValue(), byteVal);
|
||||
program.step();
|
||||
} break;
|
||||
case SLOAD:{
|
||||
|
@ -938,4 +939,4 @@ public class VM {
|
|||
|
||||
@SuppressWarnings("serial")
|
||||
private class IllegalOperationException extends RuntimeException {}
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@ package org.ethereum.core;
|
|||
|
||||
import org.ethereum.crypto.ECKey;
|
||||
import org.ethereum.crypto.HashUtil;
|
||||
import org.ethereum.db.Repository;
|
||||
import org.ethereum.db.RepositoryImpl;
|
||||
import org.ethereum.manager.WorldManager;
|
||||
import org.junit.*;
|
||||
import org.junit.runners.MethodSorters;
|
||||
|
@ -37,7 +37,7 @@ public class WalletTest {
|
|||
@Test // Testing account for simple balance set
|
||||
public void accountTest_1(){
|
||||
|
||||
Repository repository = WorldManager.getInstance().getRepository();
|
||||
RepositoryImpl repository = WorldManager.getInstance().getRepository();
|
||||
|
||||
ECKey cowKey = ECKey.fromPrivate(HashUtil.sha3("cow".getBytes()));
|
||||
repository.createAccount(cowKey.getAddress());
|
||||
|
@ -55,7 +55,7 @@ public class WalletTest {
|
|||
@Test // test account balance with pending "unblocked" transaction
|
||||
public void accountTest_2(){
|
||||
|
||||
Repository repository = WorldManager.getInstance().getRepository();
|
||||
RepositoryImpl repository = WorldManager.getInstance().getRepository();
|
||||
|
||||
ECKey cowKey = ECKey.fromPrivate(HashUtil.sha3("cow".getBytes()));
|
||||
repository.createAccount(cowKey.getAddress());
|
||||
|
|
|
@ -23,7 +23,7 @@ public class RepositoryTest {
|
|||
public void test1() {
|
||||
|
||||
String addr = "cd2a3d9f938e13cd947ec05abc7fe734df8dd826";
|
||||
Repository repository = new Repository();
|
||||
RepositoryImpl repository = new RepositoryImpl();
|
||||
|
||||
try {
|
||||
AccountState createdState = repository.createAccount(Hex.decode(addr));
|
||||
|
@ -38,7 +38,7 @@ public class RepositoryTest {
|
|||
public void test2() {
|
||||
|
||||
String addr = "cd2a3d9f938e13cd947ec05abc7fe734df8dd826";
|
||||
Repository repository = new Repository();
|
||||
RepositoryImpl repository = new RepositoryImpl();
|
||||
|
||||
try {
|
||||
BigInteger nonce0 = repository.getNonce(Hex.decode(addr));
|
||||
|
@ -61,7 +61,7 @@ public class RepositoryTest {
|
|||
public void test3() {
|
||||
|
||||
String addr = "cd2a3d9f938e13cd947ec05abc7fe734df8dd826";
|
||||
Repository repository = new Repository();
|
||||
RepositoryImpl repository = new RepositoryImpl();
|
||||
try {
|
||||
BigInteger nonce0 = repository.getNonce(Hex.decode(addr));
|
||||
|
||||
|
@ -85,7 +85,7 @@ public class RepositoryTest {
|
|||
public void test4() {
|
||||
|
||||
String addr = "cd2a3d9f938e13cd947ec05abc7fe734df8dd826";
|
||||
Repository repository = new Repository();
|
||||
RepositoryImpl repository = new RepositoryImpl();
|
||||
try {
|
||||
BigInteger balance0 = repository.getBalance(Hex.decode(addr));
|
||||
|
||||
|
@ -107,7 +107,7 @@ public class RepositoryTest {
|
|||
public void test5() {
|
||||
|
||||
String addr = "cd2a3d9f938e13cd947ec05abc7fe734df8dd826";
|
||||
Repository repository = new Repository();
|
||||
RepositoryImpl repository = new RepositoryImpl();
|
||||
try {
|
||||
BigInteger balance0 = repository.getBalance(Hex.decode(addr));
|
||||
|
||||
|
@ -133,7 +133,7 @@ public class RepositoryTest {
|
|||
public void test6() {
|
||||
|
||||
String addr = "cd2a3d9f938e13cd947ec05abc7fe734df8dd826";
|
||||
Repository repository = new Repository();
|
||||
RepositoryImpl repository = new RepositoryImpl();
|
||||
|
||||
byte[] code;
|
||||
try {
|
||||
|
@ -151,7 +151,7 @@ public class RepositoryTest {
|
|||
String codeString = "7f60c860005461012c602054000000000000000000000000000000000000000000600060206000f200";
|
||||
String codeHash = "8f0d7fc8cc6fdd688fa58ae9256310069f5659ed2a8a3af994d80350fbf1e798";
|
||||
|
||||
Repository repository = new Repository();
|
||||
RepositoryImpl repository = new RepositoryImpl();
|
||||
|
||||
try {
|
||||
byte[] code0 = repository.getCode(Hex.decode(addr));
|
||||
|
@ -174,7 +174,7 @@ public class RepositoryTest {
|
|||
String addr = "cd2a3d9f938e13cd947ec05abc7fe734df8dd826";
|
||||
String codeHash = "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470";
|
||||
|
||||
Repository repository = new Repository();
|
||||
RepositoryImpl repository = new RepositoryImpl();
|
||||
|
||||
try {
|
||||
byte[] code0 = repository.getCode(Hex.decode(addr));
|
||||
|
@ -197,7 +197,7 @@ public class RepositoryTest {
|
|||
byte[] keyBytes = Hex.decode("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470");
|
||||
DataWord key = new DataWord(keyBytes);
|
||||
|
||||
Repository repository = new Repository();
|
||||
RepositoryImpl repository = new RepositoryImpl();
|
||||
|
||||
try {
|
||||
DataWord value = repository.getStorageValue(Hex.decode(addr), key);
|
||||
|
@ -211,7 +211,7 @@ public class RepositoryTest {
|
|||
public void test10() {
|
||||
|
||||
String addr = "cd2a3d9f938e13cd947ec05abc7fe734df8dd826";
|
||||
Repository repository = new Repository();
|
||||
RepositoryImpl repository = new RepositoryImpl();
|
||||
|
||||
try {
|
||||
repository.createAccount(Hex.decode(addr));
|
||||
|
@ -233,7 +233,7 @@ public class RepositoryTest {
|
|||
String addr = "cd2a3d9f938e13cd947ec05abc7fe734df8dd826";
|
||||
String expectedStorageHash = "a737c40a4aa895fb9eb464536c376ee7c2c08eb733c8fd2353fcc62dc734f075";
|
||||
|
||||
Repository repository = new Repository();
|
||||
RepositoryImpl repository = new RepositoryImpl();
|
||||
|
||||
try {
|
||||
repository.createAccount(Hex.decode(addr));
|
||||
|
@ -283,10 +283,10 @@ public class RepositoryTest {
|
|||
String expectedStorageHash = "365ed874ad42c2b4af335212465291e03dcd1f0c5b600f40f048ed238ad61fd3";
|
||||
long expectedBalance = 333;
|
||||
|
||||
Repository origRepository = new Repository();
|
||||
RepositoryImpl origRepository = new RepositoryImpl();
|
||||
|
||||
try {
|
||||
Repository repository = origRepository.getTrack();
|
||||
RepositoryImpl repository = origRepository.getTrack();
|
||||
repository.startTracking();
|
||||
|
||||
repository.createAccount(Hex.decode(addr));
|
||||
|
@ -310,8 +310,8 @@ public class RepositoryTest {
|
|||
long expectedBalance_1 = 55500;
|
||||
long expectedBalance_2 = 0;
|
||||
|
||||
Repository origRepository = new Repository();
|
||||
Repository repository = origRepository.getTrack();
|
||||
RepositoryImpl origRepository = new RepositoryImpl();
|
||||
RepositoryImpl repository = origRepository.getTrack();
|
||||
repository.startTracking();
|
||||
|
||||
repository.createAccount(Hex.decode(addr));
|
||||
|
@ -336,8 +336,8 @@ public class RepositoryTest {
|
|||
|
||||
long expectedBalance = 55500;
|
||||
|
||||
Repository origRepository = new Repository();
|
||||
Repository repository = origRepository.getTrack();
|
||||
RepositoryImpl origRepository = new RepositoryImpl();
|
||||
RepositoryImpl repository = origRepository.getTrack();
|
||||
|
||||
try {
|
||||
repository.createAccount(Hex.decode(addr_1));
|
||||
|
|
|
@ -15,7 +15,7 @@ import static org.junit.Assert.assertEquals;
|
|||
public class UtilsTest {
|
||||
|
||||
@Test
|
||||
public void getValueShortString1() {
|
||||
public void testGetValueShortString1() {
|
||||
|
||||
String expected = "123·(10^24)";
|
||||
String result = Utils.getValueShortString(new BigInteger("123456789123445654363653463"));
|
||||
|
@ -24,7 +24,7 @@ public class UtilsTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void getValueShortString2() {
|
||||
public void testGetValueShortString2() {
|
||||
|
||||
String expected = "123·(10^3)";
|
||||
String result = Utils.getValueShortString(new BigInteger("123456"));
|
||||
|
@ -33,7 +33,7 @@ public class UtilsTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void getValueShortString3() {
|
||||
public void testGetValueShortString3() {
|
||||
|
||||
String expected = "1·(10^3)";
|
||||
String result = Utils.getValueShortString(new BigInteger("1234"));
|
||||
|
@ -42,7 +42,7 @@ public class UtilsTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void getValueShortString4() {
|
||||
public void testGetValueShortString4() {
|
||||
|
||||
String expected = "123·(10^0)";
|
||||
String result = Utils.getValueShortString(new BigInteger("123"));
|
||||
|
@ -51,7 +51,7 @@ public class UtilsTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void getValueShortString5() {
|
||||
public void testGetValueShortString5() {
|
||||
|
||||
byte[] decimal = Hex.decode("3913517ebd3c0c65000000");
|
||||
String expected = "69·(10^24)";
|
||||
|
@ -59,4 +59,4 @@ public class UtilsTest {
|
|||
|
||||
assertEquals(expected, result);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,335 @@
|
|||
package org.ethereum.vm;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.ethereum.util.ByteUtil;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ProgramMemoryTest {
|
||||
|
||||
ProgramInvokeMockImpl pi = null;
|
||||
Program program;
|
||||
ByteBuffer memory;
|
||||
|
||||
@Before
|
||||
public void createProgram() {
|
||||
program = new Program(ByteUtil.EMPTY_BYTE_ARRAY, pi);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMemSize() {
|
||||
ByteBuffer memory = ByteBuffer.allocate(64);
|
||||
program.memory = memory;
|
||||
assertEquals(64, program.getMemSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testMemorySave() {
|
||||
fail("Not yet implemented");
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testMemoryLoad() {
|
||||
fail("Not yet implemented");
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testMemoryChunk() {
|
||||
fail("Not yet implemented");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllocateMemory1() {
|
||||
|
||||
memory = ByteBuffer.allocate(64);
|
||||
int offset = 32;
|
||||
int size = 32;
|
||||
program.memory = memory;
|
||||
program.allocateMemory(offset, size);
|
||||
assertEquals(64, program.getMemSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllocateMemory2() {
|
||||
|
||||
// memory.limit() > offset, == size
|
||||
// memory.limit() < offset + size
|
||||
memory = ByteBuffer.allocate(64);
|
||||
int offset = 32;
|
||||
int size = 64;
|
||||
program.memory = memory;
|
||||
program.allocateMemory(offset, size);
|
||||
assertEquals(96, program.getMemSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllocateMemory3() {
|
||||
|
||||
// memory.limit() > offset, > size
|
||||
memory = ByteBuffer.allocate(64);
|
||||
int offset = 0;
|
||||
int size = 32;
|
||||
program.memory = memory;
|
||||
program.allocateMemory(offset, size);
|
||||
assertEquals(64, program.getMemSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllocateMemory4() {
|
||||
|
||||
memory = ByteBuffer.allocate(64);;
|
||||
int offset = 0;
|
||||
int size = 64;
|
||||
program.memory = memory;
|
||||
program.allocateMemory(offset, size);
|
||||
assertEquals(64, program.getMemSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllocateMemory5() {
|
||||
|
||||
memory = ByteBuffer.allocate(64);
|
||||
int offset = 0;
|
||||
int size = 0;
|
||||
program.memory = memory;
|
||||
program.allocateMemory(offset, size);
|
||||
assertEquals(64, program.getMemSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllocateMemory6() {
|
||||
|
||||
// memory.limit() == offset, > size
|
||||
memory = ByteBuffer.allocate(64);
|
||||
int offset = 64;
|
||||
int size = 32;
|
||||
program.memory = memory;
|
||||
program.allocateMemory(offset, size);
|
||||
assertEquals(96, program.getMemSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllocateMemory7() {
|
||||
|
||||
// memory.limit() == offset - size
|
||||
memory = ByteBuffer.allocate(64);
|
||||
int offset = 96;
|
||||
int size = 32;
|
||||
program.memory = memory;
|
||||
program.allocateMemory(offset, size);
|
||||
assertEquals(128, program.getMemSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllocateMemory8() {
|
||||
|
||||
memory = ByteBuffer.allocate(64);
|
||||
int offset = 0;
|
||||
int size = 96;
|
||||
program.memory = memory;
|
||||
program.allocateMemory(offset, size);
|
||||
assertEquals(96, program.getMemSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllocateMemory9() {
|
||||
|
||||
// memory.limit() < offset, > size
|
||||
// memory.limit() < offset - size
|
||||
memory = ByteBuffer.allocate(64);
|
||||
int offset = 96;
|
||||
int size = 0;
|
||||
program.memory = memory;
|
||||
program.allocateMemory(offset, size);
|
||||
assertEquals(96, program.getMemSize());
|
||||
}
|
||||
|
||||
/************************************************/
|
||||
|
||||
|
||||
@Test
|
||||
public void testAllocateMemory10() {
|
||||
|
||||
// memory = null, offset > size
|
||||
int offset = 32;
|
||||
int size = 0;
|
||||
program.memory = memory;
|
||||
program.allocateMemory(offset, size);
|
||||
assertEquals(32, program.getMemSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllocateMemory11() {
|
||||
|
||||
// memory = null, offset < size
|
||||
int offset = 0;
|
||||
int size = 32;
|
||||
program.memory = memory;
|
||||
program.allocateMemory(offset, size);
|
||||
assertEquals(32, program.getMemSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllocateMemory12() {
|
||||
|
||||
// memory.limit() < offset, < size
|
||||
memory = ByteBuffer.allocate(32);
|
||||
int offset = 64;
|
||||
int size = 96;
|
||||
program.memory = memory;
|
||||
program.allocateMemory(offset, size);
|
||||
assertEquals(160, program.getMemSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllocateMemory13() {
|
||||
|
||||
// memory.limit() > offset, < size
|
||||
memory = ByteBuffer.allocate(64);
|
||||
int offset = 32;
|
||||
int size = 128;
|
||||
program.memory = memory;
|
||||
program.allocateMemory(offset, size);
|
||||
assertEquals(160, program.getMemSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllocateMemory14() {
|
||||
|
||||
// memory.limit() < offset, == size
|
||||
memory = ByteBuffer.allocate(64);
|
||||
int offset = 96;
|
||||
int size = 64;
|
||||
program.memory = memory;
|
||||
program.allocateMemory(offset, size);
|
||||
assertEquals(160, program.getMemSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllocateMemory15() {
|
||||
|
||||
// memory.limit() == offset, < size
|
||||
memory = ByteBuffer.allocate(64);
|
||||
int offset = 64;
|
||||
int size = 96;
|
||||
program.memory = memory;
|
||||
program.allocateMemory(offset, size);
|
||||
assertEquals(160, program.getMemSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllocateMemory16() {
|
||||
|
||||
// memory.limit() == offset, == size
|
||||
// memory.limit() > offset - size
|
||||
memory = ByteBuffer.allocate(64);
|
||||
int offset = 64;
|
||||
int size = 64;
|
||||
program.memory = memory;
|
||||
program.allocateMemory(offset, size);
|
||||
assertEquals(128, program.getMemSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllocateMemory17() {
|
||||
|
||||
// memory.limit() > offset + size
|
||||
memory = ByteBuffer.allocate(96);
|
||||
int offset = 32;
|
||||
int size = 32;
|
||||
program.memory = memory;
|
||||
program.allocateMemory(offset, size);
|
||||
assertEquals(96, program.getMemSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllocateMemoryUnrounded1() {
|
||||
|
||||
// memory unrounded
|
||||
memory = ByteBuffer.allocate(16);
|
||||
int offset = 64;
|
||||
int size = 32;
|
||||
program.memory = memory;
|
||||
program.allocateMemory(offset, size);
|
||||
assertEquals(96, program.getMemSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllocateMemoryUnrounded2() {
|
||||
|
||||
// offset unrounded
|
||||
memory = ByteBuffer.allocate(32);
|
||||
int offset = 16;
|
||||
int size = 32;
|
||||
program.memory = memory;
|
||||
program.allocateMemory(offset, size);
|
||||
assertEquals(64, program.getMemSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllocateMemoryUnrounded3() {
|
||||
|
||||
// size unrounded
|
||||
memory = ByteBuffer.allocate(32);
|
||||
int offset = 64;
|
||||
int size = 16;
|
||||
program.memory = memory;
|
||||
program.allocateMemory(offset, size);
|
||||
assertEquals(96, program.getMemSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllocateMemoryUnrounded4() {
|
||||
|
||||
// memory + offset unrounded
|
||||
memory = ByteBuffer.allocate(16);
|
||||
int offset = 16;
|
||||
int size = 32;
|
||||
program.memory = memory;
|
||||
program.allocateMemory(offset, size);
|
||||
assertEquals(64 , program.getMemSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllocateMemoryUnrounded5() {
|
||||
|
||||
// memory + size unrounded
|
||||
memory = ByteBuffer.allocate(16);
|
||||
int offset = 32;
|
||||
int size = 16;
|
||||
program.memory = memory;
|
||||
program.allocateMemory(offset, size);
|
||||
assertEquals(64, program.getMemSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllocateMemoryUnrounded6() {
|
||||
|
||||
// offset + size unrounded
|
||||
memory = ByteBuffer.allocate(32);
|
||||
int offset = 16;
|
||||
int size = 16;
|
||||
program.memory = memory;
|
||||
program.allocateMemory(offset, size);
|
||||
assertEquals(32, program.getMemSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllocateMemoryUnrounded7() {
|
||||
|
||||
// memory + offset + size unrounded
|
||||
memory = ByteBuffer.allocate(16);
|
||||
int offset = 16;
|
||||
int size = 16;
|
||||
program.memory = memory;
|
||||
program.allocateMemory(offset, size);
|
||||
assertEquals(32,program.getMemSize());
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@ package org.ethereum.vm;
|
|||
|
||||
import org.ethereum.core.AccountState;
|
||||
import org.ethereum.crypto.HashUtil;
|
||||
import org.ethereum.db.Repository;
|
||||
import org.ethereum.db.RepositoryImpl;
|
||||
import org.junit.FixMethodOrder;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
@ -59,7 +59,7 @@ public class VMComplexTest {
|
|||
|
||||
ProgramInvokeMockImpl pi = new ProgramInvokeMockImpl();
|
||||
pi.setOwnerAddress("77045e71a7a2c50903d88e564cd72fab11e82051");
|
||||
Repository repository = pi.getRepository();
|
||||
RepositoryImpl repository = pi.getRepository();
|
||||
|
||||
repository.createAccount(callerAddrB);
|
||||
repository.addBalance(callerAddrB, new BigInteger("100000000000000000000"));
|
||||
|
@ -134,7 +134,7 @@ public class VMComplexTest {
|
|||
|
||||
ProgramInvokeMockImpl pi = new ProgramInvokeMockImpl();
|
||||
pi.setOwnerAddress(contractB_addr);
|
||||
Repository repository = pi.getRepository();
|
||||
RepositoryImpl repository = pi.getRepository();
|
||||
|
||||
byte[] contractB_addr_bytes = Hex.decode(contractB_addr);
|
||||
byte[] codeB = Hex.decode(code_b);
|
||||
|
@ -234,7 +234,7 @@ public class VMComplexTest {
|
|||
|
||||
ProgramInvokeMockImpl pi = new ProgramInvokeMockImpl();
|
||||
pi.setOwnerAddress(contractB_addr);
|
||||
Repository repository = pi.getRepository();
|
||||
RepositoryImpl repository = pi.getRepository();
|
||||
repository.createAccount(contractA_addr_bytes);
|
||||
repository.saveCode(contractA_addr_bytes, codeA);
|
||||
|
||||
|
@ -315,7 +315,7 @@ public class VMComplexTest {
|
|||
ProgramInvokeMockImpl pi = new ProgramInvokeMockImpl();
|
||||
pi.setOwnerAddress(contractA_addr);
|
||||
|
||||
Repository repository = pi.getRepository();
|
||||
RepositoryImpl repository = pi.getRepository();
|
||||
|
||||
byte[] caller_addr_bytes = Hex.decode(callerAddr);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package org.ethereum.vm;
|
||||
|
||||
import org.ethereum.db.Repository;
|
||||
import org.ethereum.db.RepositoryImpl;
|
||||
import org.ethereum.vm.Program.OutOfGasException;
|
||||
import org.junit.FixMethodOrder;
|
||||
import org.junit.Test;
|
||||
|
@ -1540,7 +1540,7 @@ public class VMTest {
|
|||
vm.step(program);
|
||||
vm.step(program);
|
||||
|
||||
Repository repository = program.result.getRepository();
|
||||
RepositoryImpl repository = program.result.getRepository();
|
||||
DataWord key = new DataWord(Hex.decode(s_expected_key));
|
||||
DataWord val = repository.getStorageValue(invoke.getOwnerAddress().getNoLeadZeroesData(), key);
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ package org.ethereum.gui;
|
|||
|
||||
import org.ethereum.core.Block;
|
||||
import org.ethereum.core.Transaction;
|
||||
import org.ethereum.db.Repository;
|
||||
import org.ethereum.db.RepositoryImpl;
|
||||
import org.ethereum.manager.WorldManager;
|
||||
import org.ethereum.vm.*;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
@ -49,7 +49,7 @@ public class ProgramPlayDialog extends JPanel implements ActionListener,
|
|||
outputList = new ArrayList<String>();
|
||||
VM vm = new VM();
|
||||
|
||||
Repository tractRepository = WorldManager.getInstance().getRepository().getTrack();
|
||||
RepositoryImpl tractRepository = WorldManager.getInstance().getRepository().getTrack();
|
||||
|
||||
Program program = new Program(code ,
|
||||
ProgramInvokeFactory.createProgramInvoke(tx, lastBlock, tractRepository));
|
||||
|
|
Loading…
Reference in New Issue