use of org.aion.base.db.IRepository in project aion by aionnetwork.
the class BlockchainIntegrationTest method testSimpleOneTokenBalanceTransfer.
@Test
public void testSimpleOneTokenBalanceTransfer() {
// generate a recipient
final Address receiverAddress = Address.wrap(ByteUtil.hexStringToBytes("CAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFE"));
StandaloneBlockchain.Bundle bundle = (new StandaloneBlockchain.Builder()).withValidatorConfiguration("simple").withDefaultAccounts().build();
StandaloneBlockchain bc = bundle.bc;
final ECKey sender = bundle.privateKeys.get(0);
final BigInteger senderInitialBalance = bc.getRepository().getBalance(Address.wrap(sender.getAddress()));
AionTransaction tx = new AionTransaction(BigInteger.valueOf(0).toByteArray(), receiverAddress, BigInteger.valueOf(100).toByteArray(), ByteUtil.EMPTY_BYTE_ARRAY, 21000L, 1L);
tx.sign(sender);
AionBlock block = bc.createNewBlock(bc.getBestBlock(), Collections.singletonList(tx), true);
assertThat(block.getTransactionsList().size()).isEqualTo(1);
assertThat(block.getTransactionsList().get(0)).isEqualTo(tx);
ImportResult connection = bc.tryToConnect(block);
assertThat(connection).isEqualTo(ImportResult.IMPORTED_BEST);
// to be sure, perform some DB tests
IRepository repo = bc.getRepository();
assertThat(repo.getBalance(receiverAddress)).isEqualTo(BigInteger.valueOf(100));
assertThat(repo.getBalance(Address.wrap(sender.getAddress()))).isEqualTo(senderInitialBalance.subtract(BigInteger.valueOf(21000)).subtract(BigInteger.valueOf(100)));
}
use of org.aion.base.db.IRepository in project aion by aionnetwork.
the class ApiWeb3Aion method eth_getCode.
public Object eth_getCode(String _address, Object _bnOrId) {
Address address = new Address(_address);
String bnOrId = "latest";
if (_bnOrId != null && !_bnOrId.equals(null))
bnOrId = _bnOrId + "";
IRepository repo = getRepoByJsonBlockId(bnOrId);
// invalid bnOrId
if (repo == null)
return null;
byte[] code = repo.getCode(address);
return TypeConverter.toJsonHex(code);
}
use of org.aion.base.db.IRepository in project aion by aionnetwork.
the class AionBlockchainImpl method isValid.
/**
* This mechanism enforces a homeostasis in terms of the time between
* blocks; a smaller period between the last two blocks results in an
* increase in the difficulty level and thus additional computation
* required, lengthening the likely next period. Conversely, if the period
* is too large, the difficulty, and expected time to the next block, is
* reduced.
*/
private boolean isValid(AionBlock block) {
if (block == null) {
return false;
}
boolean isValid = true;
if (!block.isGenesis()) {
isValid = isValid(block.getHeader());
// Sanity checks
String trieHash = Hex.toHexString(block.getTxTrieRoot());
String trieListHash = Hex.toHexString(calcTxTrie(block.getTransactionsList()));
if (!trieHash.equals(trieListHash)) {
LOG.warn("Block's given Trie Hash doesn't match: {} != {}", trieHash, trieListHash);
return false;
}
List<AionTransaction> txs = block.getTransactionsList();
if (txs != null && !txs.isEmpty()) {
IRepository parentRepo = repository;
if (!Arrays.equals(getBlockStore().getBestBlock().getHash(), block.getParentHash())) {
parentRepo = repository.getSnapshotTo(getBlockByHash(block.getParentHash()).getStateRoot());
}
Map<Address, BigInteger> nonceCache = new HashMap<>();
if (txs.parallelStream().anyMatch(tx -> !TXValidator.isValid(tx))) {
LOG.error("Some transactions in the block are invalid");
return false;
}
for (AionTransaction tx : txs) {
Address txSender = tx.getFrom();
BigInteger expectedNonce = nonceCache.get(txSender);
if (expectedNonce == null) {
expectedNonce = parentRepo.getNonce(txSender);
}
BigInteger txNonce = new BigInteger(1, tx.getNonce());
if (!expectedNonce.equals(txNonce)) {
LOG.warn("Invalid transaction: Tx nonce {} != expected nonce {} (parent nonce: {}): {}", txNonce.toString(), expectedNonce.toString(), parentRepo.getNonce(txSender), tx);
return false;
}
// update cache
nonceCache.put(txSender, expectedNonce.add(BigInteger.ONE));
}
}
}
return isValid;
}
Aggregations