use of org.ethereum.core.Repository in project rskj by rsksmart.
the class CodeReplaceTest method executeTransaction.
public TransactionExecutor executeTransaction(BlockChainImpl blockchain, Transaction tx) {
Repository track = blockchain.getRepository().startTracking();
TransactionExecutor executor = new TransactionExecutor(config, tx, 0, RskAddress.nullAddress(), blockchain.getRepository(), blockchain.getBlockStore(), null, new ProgramInvokeFactoryImpl(), blockchain.getBestBlock());
executor.init();
executor.execute();
executor.go();
executor.finalization();
track.commit();
return executor;
}
use of org.ethereum.core.Repository in project rskj by rsksmart.
the class NetworkStateExporterTest method testContracts.
@Test
public void testContracts() throws Exception {
Repository repository = new RepositoryImpl(config, new TrieStoreImpl(new HashMapDB()));
String address1String = "1000000000000000000000000000000000000000";
RskAddress addr1 = new RskAddress(address1String);
repository.createAccount(addr1);
repository.addBalance(addr1, Coin.valueOf(1L));
repository.increaseNonce(addr1);
ContractDetails contractDetails = new co.rsk.db.ContractDetailsImpl(config);
contractDetails.setCode(new byte[] { 1, 2, 3, 4 });
contractDetails.put(DataWord.ZERO, DataWord.ONE);
contractDetails.putBytes(DataWord.ONE, new byte[] { 5, 6, 7, 8 });
repository.updateContractDetails(addr1, contractDetails);
AccountState accountState = repository.getAccountState(addr1);
accountState.setStateRoot(contractDetails.getStorageHash());
repository.updateAccountState(addr1, accountState);
Map result = writeAndReadJson(repository);
Assert.assertEquals(1, result.keySet().size());
Map address1Value = (Map) result.get(address1String);
Assert.assertEquals(3, address1Value.keySet().size());
Assert.assertEquals("1", address1Value.get("balance"));
Assert.assertEquals("1", address1Value.get("nonce"));
Map contract = (Map) address1Value.get("contract");
Assert.assertEquals(2, contract.keySet().size());
Assert.assertEquals("01020304", contract.get("code"));
Map data = (Map) contract.get("data");
Assert.assertEquals(2, data.keySet().size());
Assert.assertEquals("01", data.get(Hex.toHexString(DataWord.ZERO.getData())));
Assert.assertEquals("05060708", data.get(Hex.toHexString(DataWord.ONE.getData())));
}
use of org.ethereum.core.Repository in project rskj by rsksmart.
the class NetworkStateExporterTest method testEmptyRepo.
@Test
public void testEmptyRepo() throws Exception {
Repository repository = new RepositoryImpl(config, new TrieStoreImpl(new HashMapDB()));
Map result = writeAndReadJson(repository);
Assert.assertEquals(0, result.keySet().size());
}
use of org.ethereum.core.Repository in project rskj by rsksmart.
the class ReversibleTransactionExecutor method executeTransaction.
public ProgramResult executeTransaction(Block executionBlock, RskAddress coinbase, byte[] gasPrice, byte[] gasLimit, byte[] toAddress, byte[] value, byte[] data, byte[] fromAddress) {
Repository repository = track.getSnapshotTo(executionBlock.getStateRoot()).startTracking();
byte[] nonce = repository.getNonce(new RskAddress(fromAddress)).toByteArray();
UnsignedTransaction tx = new UnsignedTransaction(nonce, gasPrice, gasLimit, toAddress, value, data, fromAddress);
TransactionExecutor executor = new TransactionExecutor(config, tx, 0, coinbase, repository, blockStore, receiptStore, programInvokeFactory, executionBlock).setLocalCall(true);
executor.init();
executor.execute();
executor.go();
executor.finalization();
return executor.getResult();
}
use of org.ethereum.core.Repository in project rskj by rsksmart.
the class Program method createContract.
@SuppressWarnings("ThrowableResultOfMethodCallIgnored")
public void createContract(DataWord value, DataWord memStart, DataWord memSize) {
if (getCallDeep() == MAX_DEPTH) {
stackPushZero();
return;
}
RskAddress senderAddress = new RskAddress(getOwnerAddress());
Coin endowment = new Coin(value.getData());
if (isNotCovers(getStorage().getBalance(senderAddress), endowment)) {
stackPushZero();
return;
}
// [1] FETCH THE CODE FROM THE MEMORY
byte[] programCode = memoryChunk(memStart.intValue(), memSize.intValue());
if (isLogEnabled) {
logger.info("creating a new contract inside contract run: [{}]", senderAddress);
}
// actual gas subtract
long gasLimit = getRemainingGas();
spendGas(gasLimit, "internal call");
// [2] CREATE THE CONTRACT ADDRESS
byte[] nonce = getStorage().getNonce(senderAddress).toByteArray();
byte[] newAddressBytes = HashUtil.calcNewAddr(getOwnerAddress().getLast20Bytes(), nonce);
RskAddress newAddress = new RskAddress(newAddressBytes);
if (byTestingSuite()) {
// This keeps track of the contracts created for a test
getResult().addCallCreate(programCode, EMPTY_BYTE_ARRAY, gasLimit, value.getNoLeadZeroesData());
}
// (THIS STAGE IS NOT REVERTED BY ANY EXCEPTION)
if (!byTestingSuite()) {
getStorage().increaseNonce(senderAddress);
}
Repository track = getStorage().startTracking();
// In case of hashing collisions, check for any balance before createAccount()
if (track.isExist(newAddress)) {
Coin oldBalance = track.getBalance(newAddress);
track.createAccount(newAddress);
track.addBalance(newAddress, oldBalance);
} else {
track.createAccount(newAddress);
}
// [4] TRANSFER THE BALANCE
track.addBalance(senderAddress, endowment.negate());
Coin newBalance = Coin.ZERO;
if (!byTestingSuite()) {
newBalance = track.addBalance(newAddress, endowment);
}
// [5] COOK THE INVOKE AND EXECUTE
InternalTransaction internalTx = addInternalTx(nonce, getGasLimit(), senderAddress, RskAddress.nullAddress(), endowment, programCode, "create");
ProgramInvoke programInvoke = programInvokeFactory.createProgramInvoke(this, new DataWord(newAddressBytes), getOwnerAddress(), value, gasLimit, newBalance, null, track, this.invoke.getBlockStore(), byTestingSuite());
ProgramResult programResult = ProgramResult.empty();
// reset return buffer right before the call
returnDataBuffer = null;
if (isNotEmpty(programCode)) {
VM vm = new VM(config, precompiledContracts);
Program program = new Program(config, precompiledContracts, blockchainConfig, programCode, programInvoke, internalTx);
vm.play(program);
programResult = program.getResult();
}
if (programResult.getException() != null || programResult.isRevert()) {
if (isLogEnabled) {
logger.debug("contract run halted by Exception: contract: [{}], exception: [{}]", newAddress, programResult.getException());
}
if (internalTx == null) {
throw new NullPointerException();
}
internalTx.reject();
programResult.rejectInternalTransactions();
programResult.rejectLogInfos();
track.rollback();
stackPushZero();
if (programResult.getException() != null) {
return;
} else {
returnDataBuffer = result.getHReturn();
}
} else {
// 4. CREATE THE CONTRACT OUT OF RETURN
byte[] code = programResult.getHReturn();
int codeLength = getLength(code);
long storageCost = (long) codeLength * GasCost.CREATE_DATA;
long afterSpend = programInvoke.getGas() - storageCost - programResult.getGasUsed();
if (afterSpend < 0) {
programResult.setException(ExceptionHelper.notEnoughSpendingGas("No gas to return just created contract", storageCost, this));
} else if (codeLength > Constants.getMaxContractSize()) {
programResult.setException(ExceptionHelper.tooLargeContractSize(Constants.getMaxContractSize(), codeLength));
} else {
programResult.spendGas(storageCost);
track.saveCode(newAddress, code);
}
track.commit();
getResult().addDeleteAccounts(programResult.getDeleteAccounts());
getResult().addLogInfos(programResult.getLogInfoList());
// IN SUCCESS PUSH THE ADDRESS INTO THE STACK
stackPush(new DataWord(newAddressBytes));
}
// 5. REFUND THE REMAIN GAS
long refundGas = gasLimit - programResult.getGasUsed();
if (refundGas > 0) {
refundGas(refundGas, "remain gas from the internal call");
if (isGasLogEnabled) {
gasLogger.info("The remaining gas is refunded, account: [{}], gas: [{}] ", Hex.toHexString(getOwnerAddress().getLast20Bytes()), refundGas);
}
}
}
Aggregations