use of co.rsk.core.Coin in project rskj by rsksmart.
the class TxsMinGasPriceRule method isValid.
@Override
public boolean isValid(Block block) {
List<Transaction> txs = block.getTransactionsList();
if (block.getMinimumGasPrice() == null) {
logger.warn("Could not retrieve block min gas priceß");
return false;
}
Coin blockMgp = block.getMinimumGasPrice();
if (CollectionUtils.isNotEmpty(block.getTransactionsList())) {
for (Transaction tx : txs) {
if (!(tx instanceof RemascTransaction) && tx.getGasPrice().compareTo(blockMgp) < 0) {
logger.warn("Tx gas price is under the Min gas Price of the block tx={}", tx.getHash());
return false;
}
}
}
return true;
}
use of co.rsk.core.Coin in project rskj by rsksmart.
the class TransactionExecutor method init.
/**
* Do all the basic validation, if the executor
* will be ready to run the transaction at the end
* set readyToExecute = true
*/
public boolean init() {
basicTxCost = tx.transactionCost(config, executionBlock);
if (localCall) {
readyToExecute = true;
return readyToExecute;
}
BigInteger txGasLimit = new BigInteger(1, tx.getGasLimit());
BigInteger curBlockGasLimit = new BigInteger(1, executionBlock.getGasLimit());
boolean cumulativeGasReached = txGasLimit.add(BigInteger.valueOf(gasUsedInTheBlock)).compareTo(curBlockGasLimit) > 0;
if (cumulativeGasReached) {
execError(String.format("Too much gas used in this block: Require: %s Got: %s", curBlockGasLimit.longValue() - toBI(tx.getGasLimit()).longValue(), toBI(tx.getGasLimit()).longValue()));
return false;
}
if (txGasLimit.compareTo(BigInteger.valueOf(basicTxCost)) < 0) {
execError(String.format("Not enough gas for transaction execution: Require: %s Got: %s", basicTxCost, txGasLimit));
return false;
}
BigInteger reqNonce = track.getNonce(tx.getSender());
BigInteger txNonce = toBI(tx.getNonce());
if (isNotEqual(reqNonce, txNonce)) {
if (logger.isWarnEnabled()) {
logger.warn("Invalid nonce: sender {}, required: {} , tx.nonce: {}, tx {}", tx.getSender(), reqNonce, txNonce, tx.getHash());
logger.warn("Transaction Data: {}", tx);
logger.warn("Tx Included in the following block: {}", this.executionBlock.getShortDescr());
}
execError(String.format("Invalid nonce: required: %s , tx.nonce: %s", reqNonce, txNonce));
return false;
}
Coin totalCost = Coin.ZERO;
if (basicTxCost > 0) {
// Estimate transaction cost only if is not a free trx
Coin txGasCost = tx.getGasPrice().multiply(txGasLimit);
totalCost = tx.getValue().add(txGasCost);
}
Coin senderBalance = track.getBalance(tx.getSender());
if (!isCovers(senderBalance, totalCost)) {
logger.warn("Not enough cash: Require: {}, Sender cash: {}, tx {}", totalCost, senderBalance, tx.getHash());
logger.warn("Transaction Data: {}", tx);
logger.warn("Tx Included in the following block: {}", this.executionBlock);
execError(String.format("Not enough cash: Require: %s, Sender cash: %s", totalCost, senderBalance));
return false;
}
// Prevent transactions with excessive address size
byte[] receiveAddress = tx.getReceiveAddress().getBytes();
if (receiveAddress != null && !Arrays.equals(receiveAddress, EMPTY_BYTE_ARRAY) && receiveAddress.length > Constants.getMaxAddressByteLength()) {
logger.warn("Receiver address to long: size: {}, tx {}", receiveAddress.length, tx.getHash());
logger.warn("Transaction Data: {}", tx);
logger.warn("Tx Included in the following block: {}", this.executionBlock);
return false;
}
if (!tx.acceptTransactionSignature(config.getBlockchainConfig().getCommonConstants().getChainId())) {
logger.warn("Transaction {} signature not accepted: {}", tx.getHash(), tx.getSignature());
logger.warn("Transaction Data: {}", tx);
logger.warn("Tx Included in the following block: {}", this.executionBlock);
panicProcessor.panic("invalidsignature", String.format("Transaction %s signature not accepted: %s", tx.getHash(), tx.getSignature()));
execError(String.format("Transaction signature not accepted: %s", tx.getSignature()));
return false;
}
readyToExecute = true;
return true;
}
use of co.rsk.core.Coin in project rskj by rsksmart.
the class TransactionExecutor method create.
private void create() {
RskAddress newContractAddress = tx.getContractAddress();
if (isEmpty(tx.getData())) {
mEndGas = toBI(tx.getGasLimit()).subtract(BigInteger.valueOf(basicTxCost));
cacheTrack.createAccount(newContractAddress);
} else {
ProgramInvoke programInvoke = programInvokeFactory.createProgramInvoke(tx, txindex, executionBlock, cacheTrack, blockStore);
this.vm = new VM(vmConfig, precompiledContracts);
BlockchainConfig configForBlock = config.getBlockchainConfig().getConfigForBlock(executionBlock.getNumber());
this.program = new Program(vmConfig, precompiledContracts, configForBlock, tx.getData(), programInvoke, tx);
// reset storage if the contract with the same address already exists
// TCK test case only - normally this is near-impossible situation in the real network
ContractDetails contractDetails = program.getStorage().getContractDetails(newContractAddress);
for (DataWord key : contractDetails.getStorageKeys()) {
program.storageSave(key, DataWord.ZERO);
}
}
Coin endowment = tx.getValue();
cacheTrack.transfer(tx.getSender(), newContractAddress, endowment);
}
use of co.rsk.core.Coin in project rskj by rsksmart.
the class TransactionExecutor method call.
private void call() {
if (!readyToExecute) {
return;
}
logger.trace("Call transaction {} {}", toBI(tx.getNonce()), tx.getHash());
RskAddress targetAddress = tx.getReceiveAddress();
// DataWord(targetAddress)) can fail with exception:
// java.lang.RuntimeException: Data word can't exceed 32 bytes:
// if targetAddress size is greater than 32 bytes.
// But init() will detect this earlier
precompiledContract = precompiledContracts.getContractForAddress(new DataWord(targetAddress.getBytes()));
if (precompiledContract != null) {
precompiledContract.init(tx, executionBlock, track, blockStore, receiptStore, result.getLogInfoList());
long requiredGas = precompiledContract.getGasForData(tx.getData());
BigInteger txGasLimit = toBI(tx.getGasLimit());
if (!localCall && txGasLimit.compareTo(BigInteger.valueOf(requiredGas)) < 0) {
// no refund
// no endowment
execError(String.format("Out of Gas calling precompiled contract 0x%s, required: %d, left: %s ", targetAddress.toString(), (requiredGas + basicTxCost), mEndGas));
mEndGas = BigInteger.ZERO;
return;
} else {
long gasUsed = requiredGas + basicTxCost;
mEndGas = txGasLimit.subtract(BigInteger.valueOf(requiredGas + basicTxCost));
// FIXME: save return for vm trace
try {
byte[] out = precompiledContract.execute(tx.getData());
result.setHReturn(out);
} catch (RuntimeException e) {
result.setException(e);
}
result.spendGas(gasUsed);
}
} else {
byte[] code = track.getCode(targetAddress);
if (isEmpty(code)) {
mEndGas = toBI(tx.getGasLimit()).subtract(BigInteger.valueOf(basicTxCost));
result.spendGas(basicTxCost);
} else {
ProgramInvoke programInvoke = programInvokeFactory.createProgramInvoke(tx, txindex, executionBlock, cacheTrack, blockStore);
this.vm = new VM(vmConfig, precompiledContracts);
BlockchainConfig configForBlock = config.getBlockchainConfig().getConfigForBlock(executionBlock.getNumber());
this.program = new Program(vmConfig, precompiledContracts, configForBlock, code, programInvoke, tx);
}
}
if (result.getException() == null) {
Coin endowment = tx.getValue();
cacheTrack.transfer(tx.getSender(), targetAddress, endowment);
}
}
use of co.rsk.core.Coin in project rskj by rsksmart.
the class RepositoryTrack method addBalance.
@Override
public Coin addBalance(RskAddress addr, Coin value) {
synchronized (repository) {
AccountState accountState = getAccountState(addr);
if (accountState == null) {
accountState = createAccount(addr);
}
getContractDetails(addr).setDirty(true);
Coin newBalance = accountState.addToBalance(value);
logger.trace("adding to balance addr: [{}], balance: [{}], delta: [{}]", addr, newBalance, value);
return newBalance;
}
}
Aggregations