/*
* Copyright (c) [2016] [ <ether.camp> ]
* This file is part of the ethereumJ library.
*
* The ethereumJ library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The ethereumJ library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the ethereumJ library. If not, see <http://www.gnu.org/licenses/>.
*/
package org.ethereum.vm.program.invoke;
import org.ethereum.core.Repository;
import org.ethereum.crypto.ECKey;
import org.ethereum.crypto.HashUtil;
import org.ethereum.datasource.inmem.HashMapDB;
import org.ethereum.db.RepositoryRoot;
import org.ethereum.db.BlockStore;
import org.ethereum.db.BlockStoreDummy;
import org.ethereum.vm.DataWord;
import org.spongycastle.util.encoders.Hex;
/**
* @author Roman Mandeleil
* @since 03.06.2014
*/
public class ProgramInvokeMockImpl implements ProgramInvoke {
private byte[] msgData;
private Repository repository;
private byte[] ownerAddress = Hex.decode("cd2a3d9f938e13cd947ec05abc7fe734df8dd826");
private final byte[] contractAddress = Hex.decode("471fd3ad3e9eeadeec4608b92d16ce6b500704cc");
// default for most tests. This can be overwritten by the test
private long gasLimit = 1000000;
public ProgramInvokeMockImpl(byte[] msgDataRaw) {
this();
this.msgData = msgDataRaw;
}
public ProgramInvokeMockImpl() {
this.repository = new RepositoryRoot(new HashMapDB<byte[]>());
this.repository.createAccount(ownerAddress);
this.repository.createAccount(contractAddress);
this.repository.saveCode(contractAddress,
Hex.decode("385E60076000396000605f556014600054601e60"
+ "205463abcddcba6040545b51602001600a525451"
+ "6040016014525451606001601e52545160800160"
+ "28525460a052546016604860003960166000f260"
+ "00603f556103e75660005460005360200235"));
}
public ProgramInvokeMockImpl(boolean defaults) {
}
/* ADDRESS op */
public DataWord getOwnerAddress() {
return new DataWord(ownerAddress);
}
/* BALANCE op */
public DataWord getBalance() {
byte[] balance = Hex.decode("0DE0B6B3A7640000");
return new DataWord(balance);
}
/* ORIGIN op */
public DataWord getOriginAddress() {
byte[] cowPrivKey = HashUtil.sha3("horse".getBytes());
byte[] addr = ECKey.fromPrivate(cowPrivKey).getAddress();
return new DataWord(addr);
}
/* CALLER op */
public DataWord getCallerAddress() {
byte[] cowPrivKey = HashUtil.sha3("monkey".getBytes());
byte[] addr = ECKey.fromPrivate(cowPrivKey).getAddress();
return new DataWord(addr);
}
/* GASPRICE op */
public DataWord getMinGasPrice() {
byte[] minGasPrice = Hex.decode("09184e72a000");
return new DataWord(minGasPrice);
}
/* GAS op */
public DataWord getGas() {
return new DataWord(gasLimit);
}
@Override
public long getGasLong() {
return gasLimit;
}
public void setGas(long gasLimit) {
this.gasLimit = gasLimit;
}
/* CALLVALUE op */
public DataWord getCallValue() {
byte[] balance = Hex.decode("0DE0B6B3A7640000");
return new DataWord(balance);
}
/*****************/
/*** msg data ***/
/**
* *************
*/
/* CALLDATALOAD op */
public DataWord getDataValue(DataWord indexData) {
byte[] data = new byte[32];
int index = indexData.value().intValue();
int size = 32;
if (msgData == null) return new DataWord(data);
if (index > msgData.length) return new DataWord(data);
if (index + 32 > msgData.length) size = msgData.length - index;
System.arraycopy(msgData, index, data, 0, size);
return new DataWord(data);
}
/* CALLDATASIZE */
public DataWord getDataSize() {
if (msgData == null || msgData.length == 0) return new DataWord(new byte[32]);
int size = msgData.length;
return new DataWord(size);
}
/* CALLDATACOPY */
public byte[] getDataCopy(DataWord offsetData, DataWord lengthData) {
int offset = offsetData.value().intValue();
int length = lengthData.value().intValue();
byte[] data = new byte[length];
if (msgData == null) return data;
if (offset > msgData.length) return data;
if (offset + length > msgData.length) length = msgData.length - offset;
System.arraycopy(msgData, offset, data, 0, length);
return data;
}
@Override
public DataWord getPrevHash() {
byte[] prevHash = Hex.decode("961CB117ABA86D1E596854015A1483323F18883C2D745B0BC03E87F146D2BB1C");
return new DataWord(prevHash);
}
@Override
public DataWord getCoinbase() {
byte[] coinBase = Hex.decode("E559DE5527492BCB42EC68D07DF0742A98EC3F1E");
return new DataWord(coinBase);
}
@Override
public DataWord getTimestamp() {
long timestamp = 1401421348;
return new DataWord(timestamp);
}
@Override
public DataWord getNumber() {
long number = 33;
return new DataWord(number);
}
@Override
public DataWord getDifficulty() {
byte[] difficulty = Hex.decode("3ED290");
return new DataWord(difficulty);
}
@Override
public DataWord getGaslimit() {
return new DataWord(gasLimit);
}
public void setGasLimit(long gasLimit) {
this.gasLimit = gasLimit;
}
public void setOwnerAddress(byte[] ownerAddress) {
this.ownerAddress = ownerAddress;
}
@Override
public boolean byTransaction() {
return true;
}
@Override
public boolean byTestingSuite() {
return false;
}
@Override
public Repository getRepository() {
return this.repository;
}
@Override
public BlockStore getBlockStore() {
return new BlockStoreDummy();
}
public void setRepository(Repository repository) {
this.repository = repository;
}
@Override
public int getCallDeep() {
return 0;
}
}