use of org.aion.zero.impl.types.TxResponse in project aion by aionnetwork.
the class AionPendingStateImpl method addPendingTransactions.
/**
* Tries to add the given transactions to the PendingState
*
* @param transactions, the list of AionTransactions to be added
* @return a list of TxResponses of the same size as the input param transactions The entries in
* the returned list of responses correspond one-to-one with the input txs
*/
private List<TxResponse> addPendingTransactions(List<AionTransaction> transactions) {
List<AionTransaction> newPending = new ArrayList<>();
List<AionTransaction> newLargeNonceTx = new ArrayList<>();
List<TxResponse> txResponses = new ArrayList<>();
int fetchLimit = calculateTxFetchNumberLimit();
for (AionTransaction tx : transactions) {
TxResponse response;
if (pendingTxCache.isInCache(tx.getSenderAddress(), tx.getNonceBI())) {
response = TxResponse.ALREADY_CACHED;
} else {
BigInteger bestPendingStateNonce = bestPendingStateNonce(tx.getSenderAddress());
int cmp = tx.getNonceBI().compareTo(bestPendingStateNonce);
boolean isFutureNonce = (cmp > 0);
boolean isBestPendingNonce = (cmp == 0);
boolean isSealed = (tx.getNonceBI().compareTo(bestRepoNonce(tx.getSenderAddress())) < 0);
if (isFutureNonce) {
response = processTxToCachePool(tx, false, newLargeNonceTx);
} else if (isBestPendingNonce) {
if (txPool.isFull()) {
response = processTxToCachePool(tx, true, newLargeNonceTx);
} else {
response = processTxToTxPool(tx, fetchLimit, newPending);
}
} else if (isSealed) {
response = TxResponse.ALREADY_SEALED;
} else {
// This case happens when this tx was received before, but never sealed,
// typically because of low energy
TxResponse implResponse = addPendingTransactionInner(tx);
if (implResponse.equals(TxResponse.REPAID)) {
newPending.add(tx);
response = TxResponse.REPAID;
addPendingTxToBackupDatabase(tx);
PooledTransaction ptx = txPool.getDroppedPoolTx();
if (ptx != null) {
fireDroppedTx(ptx.tx, TxResponse.REPAYTX_LOWPRICE.getMessage());
}
} else {
response = implResponse;
}
}
}
txResponses.add(response);
LOGGER_TX.debug("add tx [{}], result:[{}]", tx, response.getMessage());
}
LOGGER_TX.info("Wire transaction list added: total: {}, newPending: {}, cached: {}, txPool size: {}", transactions.size(), newPending, newLargeNonceTx.size(), txPool.size());
executeCallback(newPending, newLargeNonceTx);
return txResponses;
}
use of org.aion.zero.impl.types.TxResponse in project aion by aionnetwork.
the class ApiAion method createContract.
protected ApiTxResponse createContract(ArgTxCall _params) {
if (_params == null) {
return (new ApiTxResponse(TxResponse.INVALID_TX));
}
AionAddress from = _params.getFrom();
if (from == null) {
LOG.error("<create-contract msg=invalid-from-address>");
return (new ApiTxResponse(TxResponse.INVALID_FROM));
}
ECKey key = this.getAccountKey(from.toString());
if (key == null) {
LOG.debug("ApiAion.createContract - null key");
return (new ApiTxResponse(TxResponse.INVALID_ACCOUNT));
}
try {
synchronized (pendingState) {
byte[] nonce = !(_params.getNonce().equals(BigInteger.ZERO)) ? _params.getNonce().toByteArray() : pendingState.bestPendingStateNonce(new AionAddress(key.getAddress())).toByteArray();
AionTransaction tx = AionTransaction.create(key, nonce, null, _params.getValue().toByteArray(), _params.getData(), _params.getNrg(), _params.getNrgPrice(), _params.getType(), null);
TxResponse rsp = pendingState.addTransactionFromApiServer(tx);
AionAddress address = TxUtil.calculateContractAddress(tx);
return new ApiTxResponse(rsp, tx.getTransactionHash(), address);
}
} catch (Exception ex) {
LOG.error("ApiAion.createContract - exception: [{}]", ex.getMessage());
return new ApiTxResponse(TxResponse.EXCEPTION, ex);
}
}
use of org.aion.zero.impl.types.TxResponse in project aion by aionnetwork.
the class TXValidator method validateTx.
public static TxResponse validateTx(AionTransaction tx, boolean unityForkEnabled, boolean signatureSwapForkEnabled) {
TxResponse valid = cache.get(ByteArrayWrapper.wrap(tx.getTransactionHash()));
if (valid != null) {
return valid;
} else {
if (signatureSwapForkEnabled) {
if (isValidAfterSignatureSwap(tx)) {
valid = isValidAfterUnity(tx);
} else {
LOG.error("invalid tx destination!");
valid = TxResponse.INVALID_TX_DESTINATION;
}
} else if (unityForkEnabled) {
valid = isValidAfterUnity(tx);
} else {
valid = isValid0(tx);
}
cache.put(ByteArrayWrapper.wrap(tx.getTransactionHash()), valid);
return valid;
}
}
use of org.aion.zero.impl.types.TxResponse in project aion by aionnetwork.
the class TXValidatorTest method validateTxSignatureSwapForkEnabledReceiverAddressTest.
@Test
public void validateTxSignatureSwapForkEnabledReceiverAddressTest() {
boolean signatureSwapEnabled = true;
byte[] dest = RandomUtils.nextBytes(32);
dest[0] = (byte) 0xa1;
AionTransaction tx = AionTransaction.create(key, nonce, new AionAddress(dest), value, data, nrg, nrgPrice, type, null);
TxResponse response = TXValidator.validateTx(tx, unityForkEnabled, signatureSwapEnabled);
assertEquals(TxResponse.INVALID_TX_DESTINATION, response);
}
use of org.aion.zero.impl.types.TxResponse in project aion by aionnetwork.
the class TXValidatorTest method validateTxSignatureSwapForkEnabledReceiverAddressIsPreCompiledTest.
@Test
public void validateTxSignatureSwapForkEnabledReceiverAddressIsPreCompiledTest() {
boolean signatureSwapEnabled = true;
for (ContractInfo contractInfo : ContractInfo.values()) {
AionTransaction tx = AionTransaction.create(key, nonce, contractInfo.contractAddress, value, data, nrg, nrgPrice, type, null);
TxResponse response = TXValidator.validateTx(tx, unityForkEnabled, signatureSwapEnabled);
// Note: TOTAL CURRENCY contract has been disabled.
if (contractInfo.contractAddress.equals(ContractInfo.TOTAL_CURRENCY.contractAddress)) {
assertEquals(TxResponse.INVALID_TX_DESTINATION, response);
} else {
assertEquals(TxResponse.SUCCESS, response);
}
}
}
Aggregations