use of org.aion.base.db.RepositoryCache in project aion by aionnetwork.
the class ContractIntegTest method testDeployFvmContractToAnExistedAccountWith040Fork.
@Test
public void testDeployFvmContractToAnExistedAccountWith040Fork() throws IOException {
if (txType == TransactionTypes.AVM_CREATE_CODE) {
return;
}
blockchain.forkUtility.enable040Fork(0);
long nrg = 1_000_000;
long nrgPrice = energyPrice;
BigInteger value = BigInteger.ONE;
AionAddress destinationAddr = TxUtil.calculateContractAddress(deployer.toByteArray(), deployerNonce);
// create a tx the sender send some balance to the account the deployer will deploy in the
// feature.
AionTransaction tx = AionTransaction.create(senderKey, senderNonce.toByteArray(), destinationAddr, value.toByteArray(), new byte[0], nrg, nrgPrice, txType, null);
assertFalse(tx.isContractCreationTransaction());
MiningBlock block = makeBlock(tx);
assertEquals(1, block.getTransactionsList().size());
Pair<ImportResult, AionBlockSummary> result = blockchain.tryToConnectAndFetchSummary(block);
assertTrue(result.getLeft().isSuccessful());
RepositoryCache repo = blockchain.getRepository().startTracking();
assertEquals(BigInteger.ONE, repo.getBalance(destinationAddr));
BigInteger txCost = BigInteger.valueOf(nrgPrice).multiply(BigInteger.valueOf(result.getRight().getReceipts().get(0).getEnergyUsed()));
assertEquals(senderBalance.subtract(BigInteger.ONE).subtract(txCost), repo.getBalance(sender));
senderNonce = senderNonce.add(BigInteger.ONE);
String contractName = "PayableConstructor";
byte[] deployCode = getDeployCode(contractName);
// to == null signals that this is contract creation.
tx = AionTransaction.create(deployerKey, deployerNonce.toByteArray(), null, BigInteger.ZERO.toByteArray(), deployCode, nrg, nrgPrice, txType, null);
assertTrue(tx.isContractCreationTransaction());
assertEquals(Builder.DEFAULT_BALANCE, blockchain.getRepository().getBalance(deployer));
assertEquals(BigInteger.ZERO, blockchain.getRepository().getNonce(deployer));
block = makeBlock(tx);
assertEquals(1, block.getTransactionsList().size());
result = blockchain.tryToConnectAndFetchSummary(block);
assertTrue(result.getLeft().isSuccessful());
repo = blockchain.getRepository().startTracking();
AionTxExecSummary summary = result.getRight().getSummaries().get(0);
if (txType == TransactionTypes.DEFAULT) {
// "" == SUCCESS
assertEquals("", summary.getReceipt().getError());
AionAddress contract = TxUtil.calculateContractAddress(tx);
checkStateOfNewContract(repo, contractName, contract, summary.getResult(), FastVmResultCode.SUCCESS, value);
deployerNonce = deployerNonce.add(BigInteger.ONE);
checkStateOfDeployer(repo, summary, nrgPrice, BigInteger.ZERO, deployerNonce);
}
assertEquals(225787, summary.getReceipt().getEnergyUsed());
}
use of org.aion.base.db.RepositoryCache in project aion by aionnetwork.
the class ContractIntegTest method testContractDeployCodeIsEmpty.
@Test
public void testContractDeployCodeIsEmpty() throws Exception {
long nrg = 1_000_000;
long nrgPrice = energyPrice;
BigInteger value = BigInteger.ZERO;
BigInteger nonce = BigInteger.ZERO;
// to == null signals that this is contract creation.
AionTransaction tx = AionTransaction.create(deployerKey, nonce.toByteArray(), null, value.toByteArray(), new byte[0], nrg, nrgPrice, txType, null);
assertTrue(tx.isContractCreationTransaction());
assertEquals(Builder.DEFAULT_BALANCE, blockchain.getRepository().getBalance(deployer));
assertEquals(BigInteger.ZERO, blockchain.getRepository().getNonce(deployer));
MiningBlock block = makeBlock(tx);
RepositoryCache repo = blockchain.getRepository().startTracking();
AionTxExecSummary summary = executeTransaction(tx, block, repo);
if (txType == TransactionTypes.DEFAULT) {
// "" == SUCCESS
assertEquals("", summary.getReceipt().getError());
assertEquals(221000, summary.getReceipt().getEnergyUsed());
AionAddress contract = TxUtil.calculateContractAddress(tx);
assertArrayEquals(new byte[0], summary.getResult());
assertArrayEquals(new byte[0], repo.getCode(contract));
assertEquals(BigInteger.ZERO, repo.getBalance(contract));
assertEquals(BigInteger.ZERO, repo.getNonce(contract));
assertEquals(BigInteger.ONE, repo.getNonce(deployer));
} else if (txType == TransactionTypes.AVM_CREATE_CODE) {
assertEquals("Failed: invalid data", summary.getReceipt().getError());
nonce = nonce.add(BigInteger.ONE);
checkStateOfDeployer(repo, summary, nrgPrice, value, nonce);
}
BigInteger txCost = summary.getNrgUsed().multiply(BigInteger.valueOf(nrgPrice));
assertEquals(Builder.DEFAULT_BALANCE.subtract(txCost), repo.getBalance(deployer));
}
use of org.aion.base.db.RepositoryCache in project aion by aionnetwork.
the class ContractIntegTest method testFvmTransferValueToNonPayableConstructor.
@Test
public void testFvmTransferValueToNonPayableConstructor() throws Exception {
String contractName = "EmptyContract";
byte[] deployCode = getDeployCode(contractName);
long nrg = 1_000_000;
long nrgPrice = energyPrice;
// attempt to transfer value to new contract.
BigInteger value = BigInteger.ONE;
BigInteger nonce = BigInteger.ZERO;
// to == null signals that this is contract creation.
AionTransaction tx = AionTransaction.create(deployerKey, nonce.toByteArray(), null, value.toByteArray(), deployCode, nrg, nrgPrice, txType, null);
assertTrue(tx.isContractCreationTransaction());
assertEquals(Builder.DEFAULT_BALANCE, blockchain.getRepository().getBalance(deployer));
assertEquals(BigInteger.ZERO, blockchain.getRepository().getNonce(deployer));
MiningBlock block = makeBlock(tx);
RepositoryCache repo = blockchain.getRepository().startTracking();
AionTxExecSummary summary = executeTransaction(tx, block, repo);
if (txType == TransactionTypes.DEFAULT) {
assertEquals("reverted", summary.getReceipt().getError());
// all energy is not used up.
assertNotEquals(nrg, summary.getNrgUsed().longValue());
AionAddress contract = TxUtil.calculateContractAddress(tx);
checkStateOfNewContract(repo, contractName, contract, summary.getResult(), FastVmResultCode.REVERT, BigInteger.ZERO);
nonce = nonce.add(BigInteger.ONE);
} else if (txType == TransactionTypes.AVM_CREATE_CODE) {
assertEquals("Failed: invalid data", summary.getReceipt().getError());
nonce = nonce.add(BigInteger.ONE);
}
checkStateOfDeployer(repo, summary, nrgPrice, BigInteger.ZERO, nonce);
}
use of org.aion.base.db.RepositoryCache in project aion by aionnetwork.
the class ContractIntegTest method testTransferValueToPayableConstructorInsufficientFunds.
@Test
public void testTransferValueToPayableConstructorInsufficientFunds() throws Exception {
String contractName = "PayableConstructor";
byte[] deployCode = getDeployCode(contractName);
long nrg = 1_000_000;
long nrgPrice = energyPrice;
// send too much value.
BigInteger value = Builder.DEFAULT_BALANCE.add(BigInteger.ONE);
BigInteger nonce = BigInteger.ZERO;
// to == null signals that this is contract creation.
AionTransaction tx = AionTransaction.create(deployerKey, nonce.toByteArray(), null, value.toByteArray(), deployCode, nrg, nrgPrice, txType, null);
assertTrue(tx.isContractCreationTransaction());
assertEquals(Builder.DEFAULT_BALANCE, blockchain.getRepository().getBalance(deployer));
assertEquals(BigInteger.ZERO, blockchain.getRepository().getNonce(deployer));
MiningBlock block = makeBlock(tx);
RepositoryCache repo = blockchain.getRepository().startTracking();
AionTxExecSummary summary = executeTransaction(tx, block, repo);
if (txType == TransactionTypes.DEFAULT) {
assertEquals("INSUFFICIENT_BALANCE", summary.getReceipt().getError());
assertEquals(0, summary.getReceipt().getEnergyUsed());
AionAddress contract = TxUtil.calculateContractAddress(tx);
checkStateOfNewContract(repo, contractName, contract, summary.getResult(), FastVmResultCode.INSUFFICIENT_BALANCE, BigInteger.ZERO);
checkStateOfDeployerOnBadDeploy(repo);
} else if (txType == TransactionTypes.AVM_CREATE_CODE) {
assertEquals("Rejected: insufficient balance", summary.getReceipt().getError());
assertEquals(tx.getEnergyLimit(), summary.getReceipt().getEnergyUsed());
checkStateOfDeployerOnBadDeploy(repo);
}
}
use of org.aion.base.db.RepositoryCache in project aion by aionnetwork.
the class FvmBenchmark method testDB.
/**
* The following test case benchmarks database performance. It maximizes database read/write and
* minimizes cache usage.
*
* <p>It simulate the situation where there are <code>X</code> blocks, each of which contains
* <code>Y</code> transactions. Each transaction reads/writes one storage entry of an unique
* account. This whole process is repeated <code>Z</code> time.
*
* <p>There will be <code>X * Y</code> accounts created. Trie serialization/deserialization is
* expected to happen during the test.
*
* <p>NOTE: Before you run this test, make sure the database is empty, to get consistent
* results.
*/
@Test
@Ignore
public void testDB() {
AionRepositoryImpl db = AionRepositoryImpl.inst();
byte[] zeros28 = new byte[28];
int repeat = 1000;
int blocks = 32;
int transactions = 1024;
long totalWrite = 0;
long totalRead = 0;
for (int r = 1; r <= repeat; r++) {
long t1 = System.nanoTime();
for (int i = 0; i < blocks; i++) {
RepositoryCache repo = db.startTracking();
for (int j = 0; j < transactions; j++) {
AionAddress address = new AionAddress(ByteUtil.merge(zeros28, ByteUtil.intToBytes(i * 1024 + j)));
repo.addStorageRow(address, ByteArrayWrapper.wrap(FvmDataWord.fromBytes(RandomUtils.nextBytes(16)).copyOfData()), ByteArrayWrapper.wrap(ByteUtil.stripLeadingZeroes(FvmDataWord.fromBytes(RandomUtils.nextBytes(16)).copyOfData())));
}
repo.flushTo(db, true);
db.flush();
}
long t2 = System.nanoTime();
long t3 = System.nanoTime();
for (int i = 0; i < blocks; i++) {
RepositoryCache repo = db.startTracking();
for (int j = 0; j < transactions; j++) {
AionAddress address = new AionAddress(ByteUtil.merge(zeros28, ByteUtil.intToBytes(i * 1024 + j)));
FvmDataWord.fromBytes(repo.getStorageValue(address, ByteArrayWrapper.wrap(FvmDataWord.fromBytes(RandomUtils.nextBytes(16)).copyOfData())).toBytes());
}
repo.flushTo(db, true);
db.flush();
}
long t4 = System.nanoTime();
totalWrite += (t2 - t1);
totalRead += (t4 - t3);
System.out.printf("write = %7d, read = %7d, avg. write = %7d, avg. read = %7d\n", (t2 - t1) / (blocks * transactions), (t4 - t3) / (blocks * transactions), totalWrite / (r * blocks * transactions), totalRead / (r * blocks * transactions));
}
}
Aggregations