use of org.ethereum.db.ContractDetails in project rskj by rsksmart.
the class ReversibleTransactionExecutorTest method executeTransactionGreeter.
@Test
public void executeTransactionGreeter() {
TestContract greeter = TestContract.greeter();
CallTransaction.Function greeterFn = greeter.functions.get("greet");
ContractDetails contract = contractRunner.addContract(greeter.runtimeBytecode);
RskAddress from = RskAddress.nullAddress();
byte[] gasPrice = Hex.decode("00");
byte[] value = Hex.decode("00");
byte[] gasLimit = Hex.decode("f424");
Block bestBlock = factory.getBlockchain().getBestBlock();
ProgramResult result = reversibleTransactionExecutor.executeTransaction(bestBlock, bestBlock.getCoinbase(), gasPrice, gasLimit, contract.getAddress(), value, greeterFn.encode("greet me"), from.getBytes());
Assert.assertNull(result.getException());
Assert.assertArrayEquals(new String[] { "greet me" }, greeterFn.decodeResult(result.getHReturn()));
}
use of org.ethereum.db.ContractDetails in project rskj by rsksmart.
the class VM method dumpLine.
/*
* Dumping the VM state at the current operation in various styles
* - standard Not Yet Implemented
* - standard+ (owner address, program counter, operation, gas left)
* - pretty (stack, memory, storage, level, contract,
* vmCounter, internalSteps, operation
gasBefore, gasCost, memWords)
*/
private void dumpLine(OpCode op, long gasBefore, long gasCost, long memWords, Program program) {
if ("standard+".equals(vmConfig.dumpStyle())) {
switch(op) {
case STOP:
case RETURN:
case SUICIDE:
ContractDetails details = program.getStorage().getContractDetails(new RskAddress(program.getOwnerAddress()));
List<DataWord> storageKeys = new ArrayList<>(details.getStorage().keySet());
Collections.sort(storageKeys);
storageKeys.forEach(key -> dumpLogger.trace("{} {}", Hex.toHexString(key.getNoLeadZeroesData()), Hex.toHexString(details.getStorage().get(key).getNoLeadZeroesData())));
break;
default:
break;
}
String addressString = Hex.toHexString(program.getOwnerAddress().getLast20Bytes());
String pcString = Hex.toHexString(new DataWord(program.getPC()).getNoLeadZeroesData());
String opString = Hex.toHexString(new byte[] { op.val() });
String gasString = Long.toHexString(program.getRemainingGas());
dumpLogger.trace("{} {} {} {}", addressString, pcString, opString, gasString);
} else if ("pretty".equals(vmConfig.dumpStyle())) {
dumpLogger.trace("-------------------------------------------------------------------------");
dumpLogger.trace(" STACK");
program.getStack().forEach(item -> dumpLogger.trace("{}", item));
dumpLogger.trace(" MEMORY");
String memoryString = program.memoryToString();
if (!"".equals(memoryString)) {
dumpLogger.trace("{}", memoryString);
}
dumpLogger.trace(" STORAGE");
ContractDetails details = program.getStorage().getContractDetails(new RskAddress(program.getOwnerAddress()));
List<DataWord> storageKeys = new ArrayList<>(details.getStorage().keySet());
Collections.sort(storageKeys);
storageKeys.forEach(key -> dumpLogger.trace("{}: {}", key.shortHex(), details.getStorage().get(key).shortHex()));
int level = program.getCallDeep();
String contract = Hex.toHexString(program.getOwnerAddress().getLast20Bytes());
String internalSteps = String.format("%4s", Integer.toHexString(program.getPC())).replace(' ', '0').toUpperCase();
dumpLogger.trace("{} | {} | #{} | {} : {} | {} | -{} | {}x32", level, contract, vmCounter, internalSteps, op, gasBefore, gasCost, memWords);
}
}
use of org.ethereum.db.ContractDetails in project rskj by rsksmart.
the class TransactionExecutor method finalization.
public void finalization() {
if (!readyToExecute) {
return;
}
// RSK if local call gas balances must not be changed
if (localCall) {
return;
}
logger.trace("Finalize transaction {} {}", toBI(tx.getNonce()), tx.getHash());
cacheTrack.commit();
// Should include only LogInfo's that was added during not rejected transactions
List<LogInfo> notRejectedLogInfos = result.getLogInfoList().stream().filter(logInfo -> !logInfo.isRejected()).collect(Collectors.toList());
TransactionExecutionSummary.Builder summaryBuilder = TransactionExecutionSummary.builderFor(tx).gasLeftover(mEndGas).logs(notRejectedLogInfos).result(result.getHReturn());
if (result != null) {
// Accumulate refunds for suicides
result.addFutureRefund((long) result.getDeleteAccounts().size() * GasCost.SUICIDE_REFUND);
long gasRefund = Math.min(result.getFutureRefund(), result.getGasUsed() / 2);
RskAddress addr = tx.isContractCreation() ? tx.getContractAddress() : tx.getReceiveAddress();
mEndGas = mEndGas.add(BigInteger.valueOf(gasRefund));
summaryBuilder.gasUsed(toBI(result.getGasUsed())).gasRefund(toBI(gasRefund)).deletedAccounts(result.getDeleteAccounts()).internalTransactions(result.getInternalTransactions());
ContractDetails cdetails = track.getContractDetails(addr);
if (cdetails != null) {
summaryBuilder.storageDiff(cdetails.getStorage());
}
if (result.getException() != null) {
summaryBuilder.markAsFailed();
}
}
logger.trace("Building transaction execution summary");
TransactionExecutionSummary summary = summaryBuilder.build();
// Refund for gas leftover
track.addBalance(tx.getSender(), summary.getLeftover().add(summary.getRefund()));
logger.trace("Pay total refund to sender: [{}], refund val: [{}]", tx.getSender(), summary.getRefund());
// Transfer fees to miner
Coin summaryFee = summary.getFee();
// TODO: REMOVE THIS WHEN THE LocalBLockTests starts working with REMASC
if (config.isRemascEnabled()) {
logger.trace("Adding fee to remasc contract account");
track.addBalance(PrecompiledContracts.REMASC_ADDR, summaryFee);
} else {
track.addBalance(coinbase, summaryFee);
}
this.paidFees = summaryFee;
if (result != null) {
logger.trace("Processing result");
logs = notRejectedLogInfos;
result.getCodeChanges().forEach((key, value) -> track.saveCode(new RskAddress(key), value));
// Traverse list of suicides
result.getDeleteAccounts().forEach(address -> track.delete(new RskAddress(address)));
}
if (listener != null) {
listener.onTransactionExecuted(summary);
}
logger.trace("tx listener done");
if (config.vmTrace() && program != null && result != null) {
ProgramTrace trace = program.getTrace().result(result.getHReturn()).error(result.getException());
String txHash = tx.getHash().toHexString();
try {
saveProgramTraceFile(config, txHash, trace);
if (listener != null) {
listener.onVMTraceCreated(txHash, trace);
}
} catch (IOException e) {
String errorMessage = String.format("Cannot write trace to file: %s", e.getMessage());
panicProcessor.panic("executor", errorMessage);
logger.error(errorMessage);
}
}
logger.trace("tx finalization done");
}
use of org.ethereum.db.ContractDetails in project rskj by rsksmart.
the class ContractDetailsMapper method mapFromContract.
public ContractDetails mapFromContract(Contract contract) {
ContractDetails contractDetails;
contractDetails = new ContractDetailsImpl(config);
if (contract.getCode() != null) {
contractDetails.setCode(Hex.decode(contract.getCode()));
}
for (String key : contract.getData().keySet()) {
String value = contract.getData().get(key);
contractDetails.putBytes(new DataWord(Hex.decode(key)), Hex.decode(value));
}
return contractDetails;
}
use of org.ethereum.db.ContractDetails in project rskj by rsksmart.
the class GenesisLoader method generatePreMine.
private static Map<RskAddress, InitialAddressState> generatePreMine(RskSystemProperties config, BigInteger initialNonce, Map<String, AllocatedAccount> alloc) {
Map<RskAddress, InitialAddressState> premine = new HashMap<>();
ContractDetailsMapper detailsMapper = new ContractDetailsMapper(config);
for (Map.Entry<String, AllocatedAccount> accountEntry : alloc.entrySet()) {
if (!StringUtils.equals("00", accountEntry.getKey())) {
Coin balance = new Coin(new BigInteger(accountEntry.getValue().getBalance()));
BigInteger nonce;
if (accountEntry.getValue().getNonce() != null) {
nonce = new BigInteger(accountEntry.getValue().getNonce());
} else {
nonce = initialNonce;
}
AccountState acctState = new AccountState(nonce, balance);
ContractDetails contractDetails = null;
Contract contract = accountEntry.getValue().getContract();
if (contract != null) {
contractDetails = detailsMapper.mapFromContract(contract);
if (contractDetails.getCode() != null) {
acctState.setCodeHash(Keccak256Helper.keccak256(contractDetails.getCode()));
}
acctState.setStateRoot(contractDetails.getStorageHash());
}
premine.put(new RskAddress(accountEntry.getKey()), new InitialAddressState(acctState, contractDetails));
}
}
return premine;
}
Aggregations