org.aion.types.AionAddress

Here are the examples of the java api org.aion.types.AionAddress taken from open source projects. By voting up you can indicate which examples are most useful and appropriate.

851 Examples 7

19 Source : DirectoryDeployerIntegrationTest.java
with MIT License
from aionnetwork

public clreplaced DirectoryDeployerIntegrationTest {

    private static AionAddress DEPLOYER = Helpers.randomAddress();

    private static TestingBlock BLOCK = new TestingBlock(new byte[32], 1, DEPLOYER, System.currentTimeMillis(), new byte[0]);

    private static long ENERGY_LIMIT = 5_000_000L;

    private static long ENERGY_PRICE = 1L;

    @Rule
    public TemporaryFolder folder = new TemporaryFolder();

    @Test
    public void compare() throws Exception {
        // The test we are interested in is is seeing if the histogram caused by deploying a basic contract is the same when in-process and out-of-process.
        ByteArrayOutputStream captureStream = new ByteArrayOutputStream();
        TestingState kernel = new TestingState(BLOCK);
        kernel.adjustBalance(DEPLOYER, new BigInteger("10000000000000000000000"));
        IExternalCapabilities capabilities = new StandardCapabilities();
        AvmConfiguration config = new AvmConfiguration();
        config.deploymentDataHistorgramOutput = new PrintStream(captureStream);
        config.contractCaptureDirectory = folder.newFolder();
        AvmImpl avm = CommonAvmFactory.buildAvmInstanceForConfiguration(capabilities, config);
        byte[] deployment = new CodeAndArguments(UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(SimpleStackDemo.clreplaced), null).encodeToBytes();
        Transaction transaction = AvmTransactionUtil.create(DEPLOYER, kernel.getNonce(DEPLOYER), BigInteger.ZERO, deployment, ENERGY_LIMIT, ENERGY_PRICE);
        TransactionResult result = avm.run(kernel, new Transaction[] { transaction }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
        replacedert.replacedertTrue(result.transactionStatus.isSuccess());
        AionAddress contractAddress = new AionAddress(result.copyOfTransactionOutput().orElseThrow());
        String hexContract = Helpers.bytesToHexString(contractAddress.toByteArray());
        avm.shutdown();
        // By this point, we should be able to capture the output.
        String totalHistorgram = new String(captureStream.toByteArray(), StandardCharsets.UTF_8);
        // Make sure that we see the contract in that directory.
        replacedert.replacedertEquals(1, config.contractCaptureDirectory.listFiles((file) -> file.getName().equals(hexContract)).length);
        // Now, invoke the DirectoryDeployer on the captured directory and make sure its output has this histogram at the end.
        PrintStream originalStdOut = System.out;
        ByteArrayOutputStream fakeStdOutBuffer = new ByteArrayOutputStream();
        System.setOut(new PrintStream(fakeStdOutBuffer));
        DirectoryDeployer.main(new String[] { config.contractCaptureDirectory.getAbsolutePath() });
        System.setOut(originalStdOut);
        String fromCli = new String(fakeStdOutBuffer.toByteArray(), StandardCharsets.UTF_8);
        replacedert.replacedertTrue(fromCli.endsWith(totalHistorgram));
    }
}

19 Source : TrsTest.java
with MIT License
from aionnetwork

private TransactionResult withdrawFromTrs(AionAddress recipient) {
    return callContract(recipient, "withdraw");
}

19 Source : PocExchangeTest.java
with MIT License
from aionnetwork

public clreplaced PocExchangeTest {

    private static IExternalState kernel;

    private static AvmImpl avm;

    private static byte[] testERC20Jar;

    private static byte[] testExchangeJar;

    @BeforeClreplaced
    public static void setup() {
        TestingBlock block = new TestingBlock(new byte[32], 1, Helpers.randomAddress(), System.currentTimeMillis(), new byte[0]);
        kernel = new TestingState(block);
        avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new StandardCapabilities(), new AvmConfiguration());
        testERC20Jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(CoinController.clreplaced, ERC20Token.clreplaced);
        testExchangeJar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(ExchangeController.clreplaced, Exchange.clreplaced, ExchangeTransaction.clreplaced, ERC20Token.clreplaced);
    }

    @AfterClreplaced
    public static void tearDown() {
        avm.shutdown();
    }

    private long energyLimit = 6_000_0000;

    private AionAddress pepeMinter = Helpers.randomAddress();

    private AionAddress memeMinter = Helpers.randomAddress();

    private AionAddress exchangeOwner = Helpers.randomAddress();

    private AionAddress usr1 = Helpers.randomAddress();

    private AionAddress usr2 = Helpers.randomAddress();

    private AionAddress usr3 = Helpers.randomAddress();

    clreplaced CoinContract {

        private AionAddress addr;

        private AionAddress minter;

        CoinContract(AionAddress contractAddr, AionAddress minter, byte[] jar, byte[] arguments) {
            kernel.adjustBalance(minter, BigInteger.valueOf(1_000_000_000L));
            kernel.adjustBalance(pepeMinter, BigInteger.valueOf(1_000_000_000L));
            kernel.adjustBalance(memeMinter, BigInteger.valueOf(1_000_000_000L));
            kernel.adjustBalance(exchangeOwner, BigInteger.valueOf(1_000_000_000L));
            kernel.adjustBalance(usr1, BigInteger.valueOf(1_000_000_000L));
            kernel.adjustBalance(usr2, BigInteger.valueOf(1_000_000_000L));
            kernel.adjustBalance(usr3, BigInteger.valueOf(1_000_000_000L));
            this.addr = contractAddr;
            this.minter = minter;
            this.addr = initCoin(jar, arguments);
        }

        private AionAddress initCoin(byte[] jar, byte[] arguments) {
            Transaction createTransaction = AvmTransactionUtil.create(minter, kernel.getNonce(minter), BigInteger.ZERO, new CodeAndArguments(jar, arguments).encodeToBytes(), energyLimit, 1L);
            TransactionResult createResult = avm.run(kernel, new Transaction[] { createTransaction }, ExecutionType.replacedUME_MAINCHAIN, 0)[0].getResult();
            replacedert.replacedertTrue(createResult.transactionStatus.isSuccess());
            return new AionAddress(createResult.copyOfTransactionOutput().orElseThrow());
        }

        public TransactionResult callTotalSupply() {
            byte[] args = ABIUtil.encodeMethodArguments("totalSupply");
            return call(minter, args);
        }

        private TransactionResult callBalanceOf(AionAddress toQuery) {
            byte[] args = ABIUtil.encodeMethodArguments("balanceOf", new Address(toQuery.toByteArray()));
            return call(minter, args);
        }

        private TransactionResult callMint(AionAddress receiver, long amount) {
            byte[] args = ABIUtil.encodeMethodArguments("mint", new Address(receiver.toByteArray()), amount);
            return call(minter, args);
        }

        private TransactionResult callTransfer(AionAddress sender, AionAddress receiver, long amount) {
            byte[] args = ABIUtil.encodeMethodArguments("transfer", new Address(receiver.toByteArray()), amount);
            return call(sender, args);
        }

        private TransactionResult callAllowance(AionAddress owner, AionAddress spender) {
            byte[] args = ABIUtil.encodeMethodArguments("allowance", new Address(owner.toByteArray()), new Address(spender.toByteArray()));
            return call(minter, args);
        }

        private TransactionResult callApprove(AionAddress owner, AionAddress spender, long amount) {
            byte[] args = ABIUtil.encodeMethodArguments("approve", new Address(spender.toByteArray()), amount);
            return call(owner, args);
        }

        private TransactionResult callTransferFrom(AionAddress executor, AionAddress from, AionAddress to, long amount) {
            byte[] args = ABIUtil.encodeMethodArguments("transferFrom", new Address(from.toByteArray()), new Address(to.toByteArray()), amount);
            return call(executor, args);
        }

        private TransactionResult call(AionAddress sender, byte[] args) {
            Transaction callTransaction = AvmTransactionUtil.call(sender, addr, kernel.getNonce(sender), BigInteger.ZERO, args, energyLimit, 1l);
            TransactionResult callResult = avm.run(kernel, new Transaction[] { callTransaction }, ExecutionType.replacedUME_MAINCHAIN, 0)[0].getResult();
            replacedert.replacedertTrue(callResult.transactionStatus.isSuccess());
            return callResult;
        }
    }

    clreplaced ExchangeContract {

        private AionAddress addr;

        private AionAddress owner;

        ExchangeContract(AionAddress contractAddr, AionAddress owner, byte[] jar) {
            this.addr = contractAddr;
            this.owner = owner;
            this.addr = initExchange(jar, null);
        }

        private AionAddress initExchange(byte[] jar, byte[] arguments) {
            Transaction createTransaction = AvmTransactionUtil.create(owner, kernel.getNonce(owner), BigInteger.ZERO, new CodeAndArguments(jar, arguments).encodeToBytes(), energyLimit, 1L);
            TransactionResult createResult = avm.run(kernel, new Transaction[] { createTransaction }, ExecutionType.replacedUME_MAINCHAIN, 0)[0].getResult();
            replacedert.replacedertTrue(createResult.transactionStatus.isSuccess());
            return new AionAddress(createResult.copyOfTransactionOutput().orElseThrow());
        }

        public TransactionResult callListCoin(String name, AionAddress coinAddr) {
            byte[] args = ABIUtil.encodeMethodArguments("listCoin", name.toCharArray(), new Address(coinAddr.toByteArray()));
            return call(owner, args);
        }

        public TransactionResult callRequestTransfer(String name, AionAddress from, AionAddress to, long amount) {
            byte[] args = ABIUtil.encodeMethodArguments("requestTransfer", name.toCharArray(), new Address(to.toByteArray()), amount);
            return call(from, args);
        }

        public TransactionResult callProcessExchangeTransaction(AionAddress sender) {
            byte[] args = ABIUtil.encodeMethodArguments("processExchangeTransaction");
            return call(sender, args);
        }

        private TransactionResult call(AionAddress sender, byte[] args) {
            Transaction callTransaction = AvmTransactionUtil.call(sender, addr, kernel.getNonce(sender), BigInteger.ZERO, args, energyLimit, 1l);
            TransactionResult callResult = avm.run(kernel, new Transaction[] { callTransaction }, ExecutionType.replacedUME_MAINCHAIN, 0)[0].getResult();
            replacedert.replacedertTrue(callResult.transactionStatus.isSuccess());
            return callResult;
        }
    }

    @Test
    public void testERC20() {
        TransactionResult res;
        byte[] arguments = ABIUtil.encodeDeploymentArguments("Pepe", "PEPE", 8);
        CoinContract pepe = new CoinContract(null, pepeMinter, testERC20Jar, arguments);
        res = pepe.callTotalSupply();
        replacedert.replacedertEquals(0L, new ABIDecoder(res.copyOfTransactionOutput().orElseThrow()).decodeOneLong());
        res = pepe.callBalanceOf(usr1);
        replacedert.replacedertEquals(0L, new ABIDecoder(res.copyOfTransactionOutput().orElseThrow()).decodeOneLong());
        res = pepe.callBalanceOf(usr2);
        replacedert.replacedertEquals(0L, new ABIDecoder(res.copyOfTransactionOutput().orElseThrow()).decodeOneLong());
        res = pepe.callMint(usr1, 5000L);
        replacedert.replacedertEquals(true, new ABIDecoder(res.copyOfTransactionOutput().orElseThrow()).decodeOneBoolean());
        res = pepe.callBalanceOf(usr1);
        replacedert.replacedertEquals(5000L, new ABIDecoder(res.copyOfTransactionOutput().orElseThrow()).decodeOneLong());
        res = pepe.callMint(usr2, 10000L);
        replacedert.replacedertEquals(true, new ABIDecoder(res.copyOfTransactionOutput().orElseThrow()).decodeOneBoolean());
        res = pepe.callBalanceOf(usr2);
        replacedert.replacedertEquals(10000L, new ABIDecoder(res.copyOfTransactionOutput().orElseThrow()).decodeOneLong());
        res = pepe.callTransfer(usr1, usr2, 2000L);
        replacedert.replacedertEquals(true, new ABIDecoder(res.copyOfTransactionOutput().orElseThrow()).decodeOneBoolean());
        res = pepe.callBalanceOf(usr1);
        replacedert.replacedertEquals(3000L, new ABIDecoder(res.copyOfTransactionOutput().orElseThrow()).decodeOneLong());
        res = pepe.callBalanceOf(usr2);
        replacedert.replacedertEquals(12000L, new ABIDecoder(res.copyOfTransactionOutput().orElseThrow()).decodeOneLong());
        res = pepe.callAllowance(usr1, usr2);
        replacedert.replacedertEquals(0L, new ABIDecoder(res.copyOfTransactionOutput().orElseThrow()).decodeOneLong());
        res = pepe.callApprove(usr1, usr3, 1000L);
        replacedert.replacedertEquals(true, new ABIDecoder(res.copyOfTransactionOutput().orElseThrow()).decodeOneBoolean());
        res = pepe.callAllowance(usr1, usr3);
        replacedert.replacedertEquals(1000L, new ABIDecoder(res.copyOfTransactionOutput().orElseThrow()).decodeOneLong());
        res = pepe.callTransferFrom(usr3, usr1, usr2, 500L);
        replacedert.replacedertEquals(true, new ABIDecoder(res.copyOfTransactionOutput().orElseThrow()).decodeOneBoolean());
        res = pepe.callAllowance(usr1, usr3);
        replacedert.replacedertEquals(500L, new ABIDecoder(res.copyOfTransactionOutput().orElseThrow()).decodeOneLong());
        res = pepe.callBalanceOf(usr1);
        replacedert.replacedertEquals(2500L, new ABIDecoder(res.copyOfTransactionOutput().orElseThrow()).decodeOneLong());
        res = pepe.callBalanceOf(usr2);
        replacedert.replacedertEquals(12500L, new ABIDecoder(res.copyOfTransactionOutput().orElseThrow()).decodeOneLong());
    }

    @Test
    public void testExchange() {
        byte[] arguments = ABIUtil.encodeDeploymentArguments("Pepe", "PEPE", 8);
        CoinContract pepe = new CoinContract(null, pepeMinter, testERC20Jar, arguments);
        arguments = ABIUtil.encodeDeploymentArguments("Meme", "MEME", 8);
        CoinContract meme = new CoinContract(null, memeMinter, testERC20Jar, arguments);
        ExchangeContract ex = new ExchangeContract(null, exchangeOwner, testExchangeJar);
        TransactionResult res;
        res = ex.callListCoin("PEPE", pepe.addr);
        replacedert.replacedertEquals(true, new ABIDecoder(res.copyOfTransactionOutput().orElseThrow()).decodeOneBoolean());
        res = ex.callListCoin("MEME", meme.addr);
        replacedert.replacedertEquals(true, new ABIDecoder(res.copyOfTransactionOutput().orElseThrow()).decodeOneBoolean());
        res = pepe.callMint(usr1, 5000L);
        res = pepe.callMint(usr2, 5000L);
        res = pepe.callApprove(usr1, ex.addr, 2000L);
        replacedert.replacedertEquals(true, new ABIDecoder(res.copyOfTransactionOutput().orElseThrow()).decodeOneBoolean());
        res = ex.callRequestTransfer("PEPE", usr1, usr2, 1000L);
        replacedert.replacedertEquals(true, new ABIDecoder(res.copyOfTransactionOutput().orElseThrow()).decodeOneBoolean());
        res = ex.callProcessExchangeTransaction(exchangeOwner);
        replacedert.replacedertEquals(true, new ABIDecoder(res.copyOfTransactionOutput().orElseThrow()).decodeOneBoolean());
        res = pepe.callBalanceOf(usr1);
        replacedert.replacedertEquals(4000L, new ABIDecoder(res.copyOfTransactionOutput().orElseThrow()).decodeOneLong());
        res = pepe.callBalanceOf(usr2);
        replacedert.replacedertEquals(6000L, new ABIDecoder(res.copyOfTransactionOutput().orElseThrow()).decodeOneLong());
        res = pepe.callAllowance(usr1, ex.addr);
        replacedert.replacedertEquals(1000L, new ABIDecoder(res.copyOfTransactionOutput().orElseThrow()).decodeOneLong());
    }
}

19 Source : DemoTest.java
with MIT License
from aionnetwork

public clreplaced DemoTest {

    // NOTE:  Output is ONLY produced if REPORT is set to true.
    private static final boolean REPORT = false;

    private long energyLimit = 5_000_0000;

    private long energyPrice = 1;

    private AionAddress pepeMinter = Helpers.randomAddress();

    private AionAddress deployer = Helpers.randomAddress();

    private AionAddress owner1 = Helpers.randomAddress();

    private AionAddress owner2 = Helpers.randomAddress();

    private AionAddress receiver = Helpers.randomAddress();

    @Test
    public void testWallet() {
        IExternalState kernel = new TestingState();
        AvmImpl avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new StandardCapabilities(), new AvmConfiguration());
        kernel.adjustBalance(pepeMinter, BigInteger.valueOf(1_000_000_000L));
        kernel.adjustBalance(deployer, BigInteger.valueOf(1_000_000_000L));
        kernel.adjustBalance(owner1, BigInteger.valueOf(1_000_000_000L));
        kernel.adjustBalance(owner2, BigInteger.valueOf(1_000_000_000L));
        // ================
        // DEPLOY
        // ================
        report(">> Deploy \"PEPE\" ERC20 token Dapp...");
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(CoinController.clreplaced, ERC20Token.clreplaced);
        byte[] arguments = ABIUtil.encodeDeploymentArguments("Pepe", "PEPE", 8);
        // CoinContract pepe = new CoinContract(null, pepeMinter, testERC20Jar, arguments);
        Transaction createTransaction = AvmTransactionUtil.create(pepeMinter, kernel.getNonce(pepeMinter), BigInteger.ZERO, new CodeAndArguments(jar, arguments).encodeToBytes(), energyLimit, energyPrice);
        TransactionResult txResult = avm.run(kernel, new Transaction[] { createTransaction }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
        replacedertTrue(txResult.transactionStatus.isSuccess());
        Address tokenDapp = new Address(txResult.copyOfTransactionOutput().orElseThrow());
        report(">> \"PEPE\" ERC20 token Dapp is deployed. (Address " + Helpers.bytesToHexString(txResult.copyOfTransactionOutput().orElseThrow()) + ")");
        report("\n>> Deploy the Multi-sig Wallet Dapp...");
        jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(Main.clreplaced, Wallet.clreplaced, Bytes32.clreplaced);
        int confirmationsRequired = 2;
        arguments = ABIUtil.encodeDeploymentArguments(new Address(owner1.toByteArray()), new Address(owner2.toByteArray()), confirmationsRequired);
        Transaction tx = AvmTransactionUtil.create(deployer, kernel.getNonce(deployer), BigInteger.ZERO, new CodeAndArguments(jar, arguments).encodeToBytes(), energyLimit, energyPrice);
        txResult = avm.run(kernel, new Transaction[] { tx }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
        replacedertTrue(txResult.transactionStatus.isSuccess());
        Address walletDapp = new Address(txResult.copyOfTransactionOutput().orElseThrow());
        report(">> Wallet Dapp is deployed. (Address " + Helpers.bytesToHexString(txResult.copyOfTransactionOutput().orElseThrow()) + ")");
        report(">> Owners List:");
        report(">>   Deployer - (Address " + deployer + ")");
        report(">>   Owner 1  - (Address " + owner1 + ")");
        report(">>   Owner 2  - (Address " + owner2 + ")");
        report(">> Minimum number of owners to approve a transaction: " + confirmationsRequired);
        // ================
        // FUNDING and CHECK BALANCE
        // ================
        arguments = ABIUtil.encodeMethodArguments("mint", walletDapp, 5000L);
        tx = AvmTransactionUtil.call(pepeMinter, new AionAddress(tokenDapp.toByteArray()), kernel.getNonce(pepeMinter), BigInteger.ZERO, arguments, energyLimit, energyPrice);
        txResult = avm.run(kernel, new Transaction[] { tx }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
        replacedertTrue(txResult.transactionStatus.isSuccess());
        report("\n>> PEPE Mint to deliver 5000 tokens to the wallet: " + new ABIDecoder(txResult.copyOfTransactionOutput().orElseThrow()).decodeOneBoolean());
        arguments = ABIUtil.encodeMethodArguments("balanceOf", walletDapp);
        tx = AvmTransactionUtil.call(pepeMinter, new AionAddress(tokenDapp.toByteArray()), kernel.getNonce(pepeMinter), BigInteger.ZERO, arguments, energyLimit, energyPrice);
        txResult = avm.run(kernel, new Transaction[] { tx }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
        replacedertTrue(txResult.transactionStatus.isSuccess());
        report(">> balance of wallet: " + new ABIDecoder(txResult.copyOfTransactionOutput().orElseThrow()).decodeOneLong());
        arguments = ABIUtil.encodeMethodArguments("balanceOf", new Address(receiver.toByteArray()));
        tx = AvmTransactionUtil.call(pepeMinter, new AionAddress(tokenDapp.toByteArray()), kernel.getNonce(pepeMinter), BigInteger.ZERO, arguments, energyLimit, energyPrice);
        txResult = avm.run(kernel, new Transaction[] { tx }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
        replacedertTrue(txResult.transactionStatus.isSuccess());
        report(">> balance of receiver: " + new ABIDecoder(txResult.copyOfTransactionOutput().orElseThrow()).decodeOneLong());
        // ================
        // PROPOSE
        // ================
        byte[] data = ABIUtil.encodeMethodArguments("transfer", new Address(receiver.toByteArray()), 3000L);
        arguments = ABIUtil.encodeMethodArguments("propose", tokenDapp, 0L, data, energyLimit);
        tx = AvmTransactionUtil.call(deployer, new AionAddress(walletDapp.toByteArray()), kernel.getNonce(deployer), BigInteger.ZERO, arguments, 2_000_000L, energyPrice);
        txResult = avm.run(kernel, new Transaction[] { tx }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
        replacedertTrue(txResult.transactionStatus.isSuccess());
        byte[] pendingTx = new ABIDecoder(txResult.copyOfTransactionOutput().orElseThrow()).decodeOneByteArray();
        report("\n>> Deployer to propose a transaction of 3000 PEPE tokens to Receiver. (Tx ID " + Helpers.bytesToHexString(pendingTx) + ")");
        // ================
        // CONFIRM #1
        // ================
        arguments = ABIUtil.encodeMethodArguments("confirm", pendingTx);
        tx = AvmTransactionUtil.call(owner1, new AionAddress(walletDapp.toByteArray()), kernel.getNonce(owner1), BigInteger.ZERO, arguments, energyLimit, energyPrice);
        txResult = avm.run(kernel, new Transaction[] { tx }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
        replacedertTrue(txResult.transactionStatus.isSuccess());
        report(">> Transaction confirmed by Owner 1: " + new ABIDecoder(txResult.copyOfTransactionOutput().orElseThrow()).decodeOneBoolean());
        // ================
        // CONFIRM #2
        // ================
        arguments = ABIUtil.encodeMethodArguments("confirm", pendingTx);
        tx = AvmTransactionUtil.call(owner2, new AionAddress(walletDapp.toByteArray()), kernel.getNonce(owner2), BigInteger.ZERO, arguments, energyLimit, energyPrice);
        txResult = avm.run(kernel, new Transaction[] { tx }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
        replacedertTrue(txResult.transactionStatus.isSuccess());
        report(">> Transaction confirmed by Owner 2: " + new ABIDecoder(txResult.copyOfTransactionOutput().orElseThrow()).decodeOneBoolean());
        report("\n>> Number of confirmations reach to " + confirmationsRequired + ". Transaction is processed.");
        // ================
        // CHECK BALANCE
        // ================
        arguments = ABIUtil.encodeMethodArguments("balanceOf", walletDapp);
        tx = AvmTransactionUtil.call(pepeMinter, new AionAddress(tokenDapp.toByteArray()), kernel.getNonce(pepeMinter), BigInteger.ZERO, arguments, energyLimit, energyPrice);
        txResult = avm.run(kernel, new Transaction[] { tx }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
        replacedertTrue(txResult.transactionStatus.isSuccess());
        report("\n>> balance of wallet: " + new ABIDecoder(txResult.copyOfTransactionOutput().orElseThrow()).decodeOneLong());
        arguments = ABIUtil.encodeMethodArguments("balanceOf", new Address(receiver.toByteArray()));
        tx = AvmTransactionUtil.call(pepeMinter, new AionAddress(tokenDapp.toByteArray()), kernel.getNonce(pepeMinter), BigInteger.ZERO, arguments, energyLimit, energyPrice);
        txResult = avm.run(kernel, new Transaction[] { tx }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
        replacedertTrue(txResult.transactionStatus.isSuccess());
        report(">> balance of receiver: " + new ABIDecoder(txResult.copyOfTransactionOutput().orElseThrow()).decodeOneLong());
        avm.shutdown();
    }

    private static void report(String report) {
        if (REPORT) {
            System.out.println(report);
        }
    }
}

19 Source : CryptoUtilMethodFeeBenchmarkTest.java
with MIT License
from aionnetwork

/**
 * To more accurately benchmark the amount of time(resource) used for each crypto method calls,
 * we will use the following mechanism for each test:
 * - Make a few calls to method warm up the system.
 * - Make several individual calls to a single method and record the time in ns.
 *      - Average these times to get a relatively accurate setup time.
 * - Make large number of calls to a single method and benchmark the result.
 *      - Remove the setup time before averaging the time used for each call.
 *
 * Note:
 * - This test suite does explicitly cover correctness.
 * - All counters are set to 1 to avoid excess time used when running test over the whole AVM.
 * - In general, time/call will decrease logarithmically.
 *
 * Please be aware that these benchmark will have some inaccuracies, if you would like a even more
 * precise benchmark consider the following:
 * - using a profiler software such as visualvm
 * - record the times in DAppExecutor clreplaced, example [surrounding: "byte[] ret = dapp.callMain();"]
 *      long st, et;
 *      st = System.nanoTime();
 *      byte[] ret = dapp.callMain();
 *      et = System.nanoTime();
 *      System.out.println(et-st + "");
 *
 * Our summary of from the benchmark:
 * - the 3 hash functions have relatively similar speed (within 5% difference on average;
 * - edverify calls are much slower, can take anywhere between 50 to 100 times longer.
 * - length of the message has negligible effect on resources used to hash, but we should still
 * consider adding a little extra fees corresponding to msg length.
 */
public clreplaced CryptoUtilMethodFeeBenchmarkTest {

    // NOTE:  Output is ONLY produced if REPORT is set to true.
    private static final boolean REPORT = false;

    private long energyLimit = 100_000_000_000L;

    private long energyPrice = 1L;

    private AionAddress deployer = TestingState.PREMINED_ADDRESS;

    private AionAddress dappAddress;

    private TestingState kernel;

    private AvmImpl avm;

    private byte[] hashMessage = "benchmark testing".getBytes();

    private byte[] hashMessageLong = "long benchmark testing 0123456789abcdef 0123456789abcdef 0123456789abcdef 0123456789abcdef 0123456789abcdef".getBytes();

    private static final String ALPHA_NUMERIC_STRING = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

    private static final String blake2bMethodName = "callBlake2b";

    private static final String shaMethodName = "callSha";

    private static final String keccakMethodName = "callKeccak";

    private static final String edverifyMethodName = "callEdverify";

    /**
     * todo: when benchmarking, modify some of these values see more accurate results.
     * Suggest:
     * - WARMUP_COUNT >= 1000
     * - LOOP_COUNT >= 10000
     * - AVG_COUNT = 1
     * - LIST_OF_STRING_COUNT = 10000
     * - FACTOR = 100, must be a factor of LIST_OF_STRING_COUNT
     * - should focus on relative time of each method call as different systems will yield different numbers.
     */
    private static final int WARMUP_COUNT = 1;

    private static final int LOOP_COUNT = 2;

    private static final int AVG_COUNT = 1;

    private static final int LIST_OF_STRING_COUNT = 5;

    private static final int FACTOR = 1;

    @Before
    public void setup() {
        byte[] basicAppTestJar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(CryptoUtilMethodFeeBenchmarkTestTargetClreplaced.clreplaced);
        byte[] txData = new CodeAndArguments(basicAppTestJar, null).encodeToBytes();
        this.kernel = new TestingState();
        this.avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new StandardCapabilities(), new AvmConfiguration());
        Transaction tx = AvmTransactionUtil.create(deployer, kernel.getNonce(deployer), BigInteger.ZERO, txData, energyLimit, energyPrice);
        dappAddress = new AionAddress(avm.run(this.kernel, new Transaction[] { tx }, ExecutionType.replacedUME_MAINCHAIN, 0)[0].getResult().copyOfTransactionOutput().orElseThrow());
        replacedert.replacedertNotNull(dappAddress);
    }

    @After
    public void tearDown() {
        this.avm.shutdown();
    }

    /**
     * For the basic hash api benchmarks (testBlake2b, testSha, testKeccak), they should be ran
     * individually 1 by 1. Running them in sequence WILL have some effect on the results.
     */
    @Test
    public void testBlake2b() {
        // warm up
        for (int i = 0; i < WARMUP_COUNT; i++) {
            getAvgCallTime(blake2bMethodName, AVG_COUNT, 1, hashMessage);
        }
        // call method and record result, measure average call time
        long recordSum = 0;
        for (int i = 0; i < LOOP_COUNT; i++) {
            recordSum = recordSum + getCallTime(blake2bMethodName, 1, hashMessage);
        }
        report("Average time per api call for blake2b hashing: " + recordSum / LOOP_COUNT + "ns");
    }

    @Test
    public void testSha() {
        // warm up
        for (int i = 0; i < WARMUP_COUNT; i++) {
            getAvgCallTime(shaMethodName, AVG_COUNT, 1, hashMessage);
        }
        // call method and record result, measure average call time
        long recordSum = 0;
        for (int i = 0; i < LOOP_COUNT; i++) {
            recordSum = recordSum + getCallTime(shaMethodName, 1, hashMessage);
        }
        report("Average time per api call for sha hashing: " + recordSum / LOOP_COUNT + "ns");
    }

    @Test
    public void testKeccak() {
        // warm up
        for (int i = 0; i < WARMUP_COUNT; i++) {
            getAvgCallTime(keccakMethodName, AVG_COUNT, 1, hashMessage);
        }
        // call method and record result, measure average call time
        long recordSum = 0;
        for (int i = 0; i < LOOP_COUNT; i++) {
            recordSum = recordSum + getCallTime(keccakMethodName, 1, hashMessage);
        }
        report("Average time per api call for keccak hashing: " + recordSum / LOOP_COUNT + "ns");
    }

    /**
     * Compare making looping calls from outside of dapp
     */
    @Test
    public void testAll3HashFunctionsAndCompare() {
        long blake2bSum = 0;
        long shaSum = 0;
        long keccakSum = 0;
        // change this message to see variance in result
        byte[] msg = hashMessageLong;
        for (int i = 0; i < LOOP_COUNT; i++) {
            if (i < WARMUP_COUNT) {
                getCallTime(blake2bMethodName, 1, msg);
                getCallTime(shaMethodName, 1, msg);
                getCallTime(keccakMethodName, 1, msg);
            } else {
                blake2bSum = blake2bSum + getCallTime(blake2bMethodName, 1, msg);
                shaSum = shaSum + getCallTime(shaMethodName, 1, msg);
                keccakSum = keccakSum + getCallTime(keccakMethodName, 1, msg);
            }
        }
        long blake2bTimePerCall = blake2bSum / (LOOP_COUNT - WARMUP_COUNT);
        long shaTimePerCall = shaSum / (LOOP_COUNT - WARMUP_COUNT);
        long keccakTimePerCall = keccakSum / (LOOP_COUNT - WARMUP_COUNT);
        report("blake2b avg: " + blake2bTimePerCall);
        report("sha avg: " + shaTimePerCall + ", is " + String.format("%.3f", (double) shaTimePerCall / blake2bTimePerCall) + " times speed comparing to blake2b");
        report("keccak avg: " + keccakTimePerCall + ", is " + String.format("%.3f", (double) keccakTimePerCall / blake2bTimePerCall) + " times speed comparing to blake2b");
    }

    /**
     * Compare making looping calls from within the dapp
     */
    @Test
    public void testAll3HashFunctionsAndCompare2() {
        // following values should be increased for a more accurate result
        // recommended values are 1000, 1000000
        int warmUp = WARMUP_COUNT;
        int loopCount = LOOP_COUNT;
        // change this message to see variance in result
        byte[] msg = hashMessageLong;
        // warm up blake2b, then make multiple calls within the dapp
        for (int i = 0; i < warmUp; i++) {
            getAvgCallTime(blake2bMethodName, AVG_COUNT, 1, hashMessage);
        }
        long blake2bTime = getCallTime(blake2bMethodName, loopCount, msg);
        report("blake2b avg: " + blake2bTime);
        // warm up sha, then make multiple calls within the dapp
        for (int i = 0; i < warmUp; i++) {
            getAvgCallTime(shaMethodName, AVG_COUNT, 1, hashMessage);
        }
        long shaSumTime = getCallTime(shaMethodName, loopCount, msg);
        report("sha avg: " + shaSumTime + ", is " + String.format("%.3f", (double) shaSumTime / blake2bTime) + " times speed comparing to blake2b");
        // warm up keccak, then make multiple calls within the dapp
        for (int i = 0; i < warmUp; i++) {
            getAvgCallTime(keccakMethodName, AVG_COUNT, 1, hashMessage);
        }
        long keccakTime = getCallTime(keccakMethodName, loopCount, msg);
        report("keccak avg: " + keccakTime + ", is " + String.format("%.3f", (double) keccakTime / blake2bTime) + " times speed comparing to blake2b");
    }

    @Test
    public void testAll3HashFunctionsLargeInput() {
        int loopCount = LOOP_COUNT;
        int messageSize = 100000;
        for (int i = 0; i < WARMUP_COUNT; i++) {
            getAvgCallTime(blake2bMethodName, AVG_COUNT, 1, hashMessage);
        }
        double blake2bAvg = getAvgCallTime("blake2bLargeInput", AVG_COUNT, loopCount, messageSize);
        report("blake2b avg for " + messageSize + " bytes input:" + blake2bAvg);
        for (int i = 0; i < WARMUP_COUNT; i++) {
            getAvgCallTime(shaMethodName, AVG_COUNT, 1, hashMessage);
        }
        double sha256Sum = getAvgCallTime("shaLargeInput", AVG_COUNT, loopCount, messageSize);
        report("sha256 avg for " + messageSize + " bytes input:" + sha256Sum);
        for (int i = 0; i < WARMUP_COUNT; i++) {
            getAvgCallTime(keccakMethodName, AVG_COUNT, 1, hashMessage);
        }
        double keccakSum = getAvgCallTime("keccakLargeInput", AVG_COUNT, loopCount, messageSize);
        report("keccak avg for " + messageSize + " bytes input:" + keccakSum);
    }

    /**
     * Compare edverify to blake2b
     */
    @Test
    public void testEdverifyComparisionToBlake2bInDepth() {
        // following values should be increased for a more accurate result
        int warmUp = WARMUP_COUNT;
        int loopCount = LOOP_COUNT;
        // change this message to see variance in result
        byte[] msg = hashMessageLong;
        // warm up blake2b, then make multiple calls within the dapp
        for (int i = 0; i < warmUp; i++) {
            getAvgCallTime(blake2bMethodName, AVG_COUNT, 1, hashMessage);
        }
        long blake2bTime = getCallTime(blake2bMethodName, loopCount, msg);
        report("blake2b avg: " + blake2bTime);
        // warm up blake2b, then make multiple calls within the dapp
        for (int i = 0; i < warmUp; i++) {
            getAvgCallTime(edverifyMethodName, AVG_COUNT, 1, hashMessage);
        }
        long edverifyTime = getCallTime(edverifyMethodName, loopCount, msg);
        report("edverify avg: " + edverifyTime + ", which is " + String.format("%.3f", (double) edverifyTime / blake2bTime) + " times speed comparing to blake2b");
    }

    /**
     * benchmark how message length can affect time it takes to hash for each algorithm
     */
    @Test
    public void testBlake2bMessageLength() {
        String[] listOfMessage = generateListOfStrings(LIST_OF_STRING_COUNT);
        for (int i = 0; i < LIST_OF_STRING_COUNT; i = i + FACTOR) {
            long time = getCallTime(blake2bMethodName, 1, listOfMessage[i].getBytes());
            report("Signing using blake2b: msg length = " + i + 1 + " time = " + time);
        }
    }

    @Test
    public void testShaMessageLength() {
        String[] listOfMessage = generateListOfStrings(LIST_OF_STRING_COUNT);
        for (int i = 0; i < LIST_OF_STRING_COUNT; i = i + FACTOR) {
            long time = getCallTime(shaMethodName, 1, listOfMessage[i].getBytes());
            report("Signing using sha: msg length = " + i + 1 + " time = " + time);
        }
    }

    @Test
    public void testKeccakMessageLength() {
        String[] listOfMessage = generateListOfStrings(LIST_OF_STRING_COUNT);
        for (int i = 0; i < LIST_OF_STRING_COUNT; i = i + FACTOR) {
            long time = getCallTime(keccakMethodName, 1, listOfMessage[i].getBytes());
            report("Signing using keccak: msg length = " + i + 1 + " time = " + time);
        }
    }

    /**
     * Helper methods for benchmark
     */
    private double getAvgCallTime(String methodName, int loopCount, Object... arguments) {
        long sum = 0;
        for (int i = 0; i < loopCount; i++) {
            sum = sum + getCallTime(methodName, arguments);
        }
        return sum / loopCount;
    }

    private long getCallTime(String methodName, Object... arguments) {
        long st;
        long et;
        Transaction tx = setupTransaction(methodName, arguments);
        st = System.nanoTime();
        TransactionResult result = avm.run(this.kernel, new Transaction[] { tx }, ExecutionType.replacedUME_MAINCHAIN, 0)[0].getResult();
        et = System.nanoTime();
        replacedert.replacedertTrue(result.transactionStatus.isSuccess());
        return et - st;
    }

    private Transaction setupTransaction(String methodName, java.lang.Object... arguments) {
        byte[] txData = ABIUtil.encodeMethodArguments(methodName, arguments);
        return AvmTransactionUtil.call(deployer, dappAddress, kernel.getNonce(deployer), BigInteger.ZERO, txData, energyLimit, energyPrice);
    }

    private String[] generateListOfStrings(int count) {
        String[] listOfString = new String[count];
        for (int i = 0; i < count; i = i + FACTOR) {
            listOfString[i] = generateString(i + 1);
        }
        return listOfString;
    }

    private String generateString(int count) {
        StringBuilder builder = new StringBuilder();
        while (count-- != 0) {
            double n = (Math.random() * ALPHA_NUMERIC_STRING.length());
            builder.append(ALPHA_NUMERIC_STRING.charAt((int) n));
        }
        return builder.toString();
    }

    private static void report(String output) {
        if (REPORT) {
            System.out.println(output);
        }
    }
}

19 Source : AionBufferPerfTest.java
with MIT License
from aionnetwork

public clreplaced AionBufferPerfTest {

    // NOTE:  Output is ONLY produced if REPORT is set to true.
    private static final boolean REPORT = false;

    private AionAddress from = TestingState.PREMINED_ADDRESS;

    private long energyLimit = 100_000_000L;

    private long energyPrice = 1;

    private byte[] buildBufferPerfJar() {
        return UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(AionBufferPerfContract.clreplaced);
    }

    private TransactionResult deploy(IExternalState kernel, AvmImpl avm, byte[] testJar) {
        byte[] testWalletArguments = new byte[0];
        Transaction createTransaction = AvmTransactionUtil.create(from, kernel.getNonce(from), BigInteger.ZERO, new CodeAndArguments(testJar, testWalletArguments).encodeToBytes(), energyLimit, energyPrice);
        TransactionResult createResult = avm.run(kernel, new Transaction[] { createTransaction }, ExecutionType.replacedUME_MAINCHAIN, 0)[0].getResult();
        replacedert.replacedertTrue(createResult.transactionStatus.isSuccess());
        return createResult;
    }

    private TransactionResult call(IExternalState kernel, AvmImpl avm, AionAddress contract, AionAddress sender, byte[] args) {
        Transaction callTransaction = AvmTransactionUtil.call(sender, contract, kernel.getNonce(sender), BigInteger.ZERO, args, energyLimit, 1L);
        TransactionResult callResult = avm.run(kernel, new Transaction[] { callTransaction }, ExecutionType.replacedUME_MAINCHAIN, 0)[0].getResult();
        replacedert.replacedertTrue(callResult.transactionStatus.isSuccess());
        return callResult;
    }

    @Test
    public void testBuffer() {
        report(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
        report(">> Energy measurements for AionBuffer\n>>");
        byte[] args;
        TestingBlock block = new TestingBlock(new byte[32], 1, Helpers.randomAddress(), System.currentTimeMillis(), new byte[0]);
        IExternalState kernel = new TestingState(block);
        AvmImpl avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new StandardCapabilities(), new AvmConfiguration());
        TransactionResult deployRes = deploy(kernel, avm, buildBufferPerfJar());
        AionAddress contract = new AionAddress(deployRes.copyOfTransactionOutput().orElseThrow());
        args = ABIUtil.encodeMethodArguments("callPutByte");
        TransactionResult putByteResult = call(kernel, avm, contract, from, args);
        report(">> putByte()           : " + putByteResult.energyUsed / AionBufferPerfContract.NUM_ELEMENTS);
        args = ABIUtil.encodeMethodArguments("callGetByte");
        TransactionResult getByteResult = call(kernel, avm, contract, from, args);
        report(">> getByte()           : " + getByteResult.energyUsed / AionBufferPerfContract.NUM_ELEMENTS);
        args = ABIUtil.encodeMethodArguments("callPutChar");
        TransactionResult putCharResult = call(kernel, avm, contract, from, args);
        report(">> putChar()           : " + putCharResult.energyUsed / AionBufferPerfContract.NUM_ELEMENTS);
        args = ABIUtil.encodeMethodArguments("callGetChar");
        TransactionResult getCharResult = call(kernel, avm, contract, from, args);
        report(">> getChar()           : " + getCharResult.energyUsed / AionBufferPerfContract.NUM_ELEMENTS);
        args = ABIUtil.encodeMethodArguments("callPutShort");
        TransactionResult putShortResult = call(kernel, avm, contract, from, args);
        report(">> putShort()          : " + putShortResult.energyUsed / AionBufferPerfContract.NUM_ELEMENTS);
        args = ABIUtil.encodeMethodArguments("callGetShort");
        TransactionResult getShortResult = call(kernel, avm, contract, from, args);
        report(">> getShort()          : " + getShortResult.energyUsed / AionBufferPerfContract.NUM_ELEMENTS);
        args = ABIUtil.encodeMethodArguments("callPutInt");
        TransactionResult putIntResult = call(kernel, avm, contract, from, args);
        report(">> putInt()            : " + putIntResult.energyUsed / AionBufferPerfContract.NUM_ELEMENTS);
        args = ABIUtil.encodeMethodArguments("callGetInt");
        TransactionResult getIntResult = call(kernel, avm, contract, from, args);
        report(">> getInt()            : " + getIntResult.energyUsed / AionBufferPerfContract.NUM_ELEMENTS);
        args = ABIUtil.encodeMethodArguments("callPutFloat");
        TransactionResult putFloatResult = call(kernel, avm, contract, from, args);
        report(">> putFloat()          : " + putFloatResult.energyUsed / AionBufferPerfContract.NUM_ELEMENTS);
        args = ABIUtil.encodeMethodArguments("callGetFloat");
        TransactionResult getFloatResult = call(kernel, avm, contract, from, args);
        report(">> getFloat()          : " + getFloatResult.energyUsed / AionBufferPerfContract.NUM_ELEMENTS);
        args = ABIUtil.encodeMethodArguments("callPutLong");
        TransactionResult putLongResult = call(kernel, avm, contract, from, args);
        report(">> putLong()           : " + putLongResult.energyUsed / AionBufferPerfContract.NUM_ELEMENTS);
        args = ABIUtil.encodeMethodArguments("callGetLong");
        TransactionResult getLongResult = call(kernel, avm, contract, from, args);
        report(">> getLong()           : " + getLongResult.energyUsed / AionBufferPerfContract.NUM_ELEMENTS);
        args = ABIUtil.encodeMethodArguments("callPutDouble");
        TransactionResult putDoubleResult = call(kernel, avm, contract, from, args);
        report(">> putDouble()         : " + putDoubleResult.energyUsed / AionBufferPerfContract.NUM_ELEMENTS);
        args = ABIUtil.encodeMethodArguments("callGetDouble");
        TransactionResult getDoubleResult = call(kernel, avm, contract, from, args);
        report(">> getDouble()         : " + getDoubleResult.energyUsed / AionBufferPerfContract.NUM_ELEMENTS);
        args = ABIUtil.encodeMethodArguments("callPutAddress");
        TransactionResult putAddressResult = call(kernel, avm, contract, from, args);
        report(">> putAddress()         : " + putAddressResult.energyUsed / AionBufferPerfContract.BIG_ELT_COUNT);
        args = ABIUtil.encodeMethodArguments("callGetAddress");
        TransactionResult getAddressResult = call(kernel, avm, contract, from, args);
        report(">> getAddress()         : " + getAddressResult.energyUsed / AionBufferPerfContract.BIG_ELT_COUNT);
        args = ABIUtil.encodeMethodArguments("callPutBigInt");
        TransactionResult putBigIntResult = call(kernel, avm, contract, from, args);
        report(">> putBigInt()         : " + putBigIntResult.energyUsed / AionBufferPerfContract.BIG_ELT_COUNT);
        args = ABIUtil.encodeMethodArguments("callGetBigInt");
        TransactionResult getBigIntResult = call(kernel, avm, contract, from, args);
        report(">> getBigInt()         : " + getBigIntResult.energyUsed / AionBufferPerfContract.BIG_ELT_COUNT);
        args = ABIUtil.encodeMethodArguments("callTransferBytesToBuffer");
        TransactionResult putResult = call(kernel, avm, contract, from, args);
        report(">> put()               : " + putResult.energyUsed / AionBufferPerfContract.NUM_ELEMENTS + "     (for transfers of " + AionBufferPerfContract.TRANSFER_SIZE + " bytes)");
        args = ABIUtil.encodeMethodArguments("callTransferBytesFromBuffer");
        TransactionResult getResult = call(kernel, avm, contract, from, args);
        report(">> get()               : " + getResult.energyUsed / AionBufferPerfContract.NUM_ELEMENTS + "     (for transfers of " + AionBufferPerfContract.TRANSFER_SIZE + " bytes)");
        args = ABIUtil.encodeMethodArguments("callEquals");
        TransactionResult equalsResult = call(kernel, avm, contract, from, args);
        report(">> equals()            : " + equalsResult.energyUsed / AionBufferPerfContract.NUM_ELEMENTS);
        avm.shutdown();
        report("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
    }

    private static void report(String output) {
        if (REPORT) {
            System.out.println(output);
        }
    }
}

19 Source : DirectoryDeployer.java
with MIT License
from aionnetwork

/**
 * A tool to run our data collection histogram against pre-created contracts.
 * Point this at a directory containing code and argument data and it will deploy every contract found, with corresponding argument data.
 * The expected shape of the directory given is produced by the AvmConfiguration.contractCaptureDirectory option.
 *
 * NOTE:  This currently deploys 1 contract at a time, in the order they are found in the directory, using the same emulated block.
 * In the future, this may be changed to deploy them in the order and blocks defined by the other meta-data.
 */
public clreplaced DirectoryDeployer {

    private static AionAddress DEPLOYER = Helpers.randomAddress();

    private static TestingBlock BLOCK = new TestingBlock(new byte[32], 1, DEPLOYER, System.currentTimeMillis(), new byte[0]);

    private static long ENERGY_LIMIT = 5_000_000L;

    private static long ENERGY_PRICE = 1L;

    public static void main(String[] args) {
        TestingState kernel = new TestingState(BLOCK);
        kernel.adjustBalance(DEPLOYER, new BigInteger("10000000000000000000000"));
        IExternalCapabilities capabilities = new StandardCapabilities();
        AvmConfiguration config = new AvmConfiguration();
        config.deploymentDataHistorgramOutput = System.out;
        AvmImpl avm = CommonAvmFactory.buildAvmInstanceForConfiguration(capabilities, config);
        File rootDirectory = new File(args[0]);
        replacedertTrue(rootDirectory.isDirectory());
        int preplacedCount = 0;
        int failCount = 0;
        for (String name : rootDirectory.list()) {
            try {
                Transaction transaction = createTransaction(kernel, new File(rootDirectory, name));
                FutureResult[] futures = avm.run(kernel, new Transaction[] { transaction }, ExecutionType.replacedUME_MAINCHAIN, 0);
                boolean success = futures[0].getResult().transactionStatus.isSuccess();
                if (success) {
                    preplacedCount += 1;
                } else {
                    failCount += 1;
                }
                System.out.println(name + ": " + (success ? "Preplaced" : "FAIL"));
            } catch (IOException e) {
                System.err.println(name);
                e.printStackTrace();
                System.exit(1);
            }
        }
        System.out.println("Attempted " + (preplacedCount + failCount) + " deployments (" + preplacedCount + " preplaceded, " + failCount + " failed)");
        avm.shutdown();
    }

    private static Transaction createTransaction(IExternalState kernel, File directory) throws IOException {
        // For now, we will only load the code and the arguments.
        byte[] code = Files.readAllBytes(new File(directory, "code.jar").toPath());
        File argFile = new File(directory, "arguments.bin");
        byte[] args = argFile.exists() ? Files.readAllBytes(argFile.toPath()) : new byte[0];
        byte[] createData = new CodeAndArguments(code, args).encodeToBytes();
        return AvmTransactionUtil.create(DEPLOYER, kernel.getNonce(DEPLOYER), BigInteger.ZERO, createData, ENERGY_LIMIT, ENERGY_PRICE);
    }

    private static void replacedertTrue(boolean flag) {
        // We use a private helper to manage the replacedertions since the JDK default disables them.
        if (!flag) {
            throw new replacedertionError("Case must be true");
        }
    }
}

19 Source : AvmCLI.java
with MIT License
from aionnetwork

public static void reportDeployRequest(IEnvironment env, String storagePath, String jarPath, AionAddress sender) {
    lineSeparator(env);
    env.logLine("DApp deployment request");
    env.logLine("Storage      : " + storagePath);
    env.logLine("Dapp Jar     : " + jarPath);
    env.logLine("Sender       : " + sender);
}

19 Source : AvmCLI.java
with MIT License
from aionnetwork

private static void reportCallRequest(IEnvironment env, String storagePath, AionAddress contract, AionAddress sender, String method, Object[] args) {
    lineSeparator(env);
    env.logLine("DApp call request");
    env.logLine("Storage      : " + storagePath);
    env.logLine("Dapp Address : " + contract);
    env.logLine("Sender       : " + sender);
    env.logLine("Method       : " + method);
    env.logLine("Arguments    : ");
    for (int i = 0; i < args.length; i += 2) {
        env.logLine("             : " + args[i]);
    }
}

19 Source : AvmParallelTest.java
with MIT License
from aionnetwork

public clreplaced AvmParallelTest {

    private AionAddress preminedAddress = TestingState.PREMINED_ADDRESS;

    private TestingBlock block = new TestingBlock(new byte[32], 1, Helpers.randomAddress(), System.currentTimeMillis(), new byte[0]);

    @Test
    public void basicConcurrencyTest() {
        TestingState kernel = new TestingState(block);
        AvmImpl avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
        AionAddress usr1 = new AionAddress(Helpers.hexStringToBytes("1111111111111111111111111111111111111111111111111111111111111111"));
        BigInteger expected1 = BigInteger.ZERO;
        Transaction t0 = AvmTransactionUtil.call(preminedAddress, usr1, BigInteger.ZERO, BigInteger.valueOf(500_000), new byte[0], 100000L, 1);
        Transaction t1 = AvmTransactionUtil.call(preminedAddress, usr1, BigInteger.ONE, BigInteger.valueOf(500_000), new byte[0], 100000L, 1);
        Transaction t2 = AvmTransactionUtil.call(preminedAddress, usr1, BigInteger.TWO, BigInteger.valueOf(500_000), new byte[0], 100000L, 1);
        Transaction t3 = AvmTransactionUtil.call(preminedAddress, usr1, BigInteger.valueOf(3), BigInteger.valueOf(500_000), new byte[0], 100000L, 1);
        Transaction t4 = AvmTransactionUtil.call(preminedAddress, usr1, BigInteger.valueOf(4), BigInteger.valueOf(500_000), new byte[0], 100000L, 1);
        Transaction[] batch = new Transaction[] { t0, t1, t2, t3, t4 };
        FutureResult[] results = avm.run(kernel, batch, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1);
        for (FutureResult f : results) {
            f.getResult();
        }
        expected1 = expected1.add(BigInteger.valueOf(500_000 * 5));
        replacedert.replacedertEquals(expected1, kernel.getBalance(usr1));
        AionAddress usr2 = new AionAddress(Helpers.hexStringToBytes("2222222222222222222222222222222222222222222222222222222222222222"));
        BigInteger expected2 = BigInteger.ZERO;
        t0 = AvmTransactionUtil.call(usr1, usr2, BigInteger.ZERO, BigInteger.valueOf(100_000), new byte[0], 100000L, 1);
        t1 = AvmTransactionUtil.call(usr1, usr2, BigInteger.ONE, BigInteger.valueOf(100_000), new byte[0], 100000L, 1);
        t2 = AvmTransactionUtil.call(usr1, usr2, BigInteger.TWO, BigInteger.valueOf(100_000), new byte[0], 100000L, 1);
        t3 = AvmTransactionUtil.call(usr1, usr2, BigInteger.valueOf(3), BigInteger.valueOf(100_000), new byte[0], 100000L, 1);
        t4 = AvmTransactionUtil.call(usr1, usr2, BigInteger.valueOf(4), BigInteger.valueOf(100_000), new byte[0], 100000L, 1);
        batch = new Transaction[] { t0, t1, t2, t3, t4 };
        results = avm.run(kernel, batch, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1);
        for (FutureResult f : results) {
            f.getResult();
        }
        expected1 = expected1.subtract(BigInteger.valueOf(100_000 * 5)).subtract(BigInteger.valueOf(BillingRules.getBasicTransactionCost(t1.copyOfTransactionData()) * 5));
        expected2 = BigInteger.valueOf(100_000 * 5);
        replacedert.replacedertEquals(expected1, kernel.getBalance(usr1));
        replacedert.replacedertEquals(expected2, kernel.getBalance(usr2));
        t0 = AvmTransactionUtil.call(usr1, usr2, BigInteger.ZERO, BigInteger.valueOf(100_000), new byte[0], 100000L, 1);
        t1 = AvmTransactionUtil.call(usr2, usr1, BigInteger.ONE, BigInteger.valueOf(100_000), new byte[0], 100000L, 1);
        int iteration = 10;
        batch = new Transaction[iteration * 2];
        for (int i = 0; i < iteration; i++) {
            batch[i * 2] = AvmTransactionUtil.call(usr1, usr2, BigInteger.valueOf(5 + i), BigInteger.valueOf(100_000), new byte[0], 100000L, 1);
            batch[i * 2 + 1] = AvmTransactionUtil.call(usr2, usr1, BigInteger.valueOf(i), BigInteger.valueOf(100_000), new byte[0], 100000L, 1);
        }
        results = avm.run(kernel, batch, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1);
        for (FutureResult f : results) {
            f.getResult();
        }
        expected1 = expected1.subtract(BigInteger.valueOf(BillingRules.getBasicTransactionCost(t0.copyOfTransactionData()) * iteration));
        expected2 = expected2.subtract(BigInteger.valueOf(BillingRules.getBasicTransactionCost(t1.copyOfTransactionData()) * iteration));
        replacedert.replacedertEquals(expected1, kernel.getBalance(usr1));
        replacedert.replacedertEquals(expected2, kernel.getBalance(usr2));
        avm.shutdown();
    }

    @Test
    public void cyclicWaitTest() {
        TestingState kernel = new TestingState(block);
        AvmImpl avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
        AionAddress usr1 = new AionAddress(Helpers.hexStringToBytes("1111111111111111111111111111111111111111111111111111111111111111"));
        AionAddress usr2 = new AionAddress(Helpers.hexStringToBytes("2222222222222222222222222222222222222222222222222222222222222222"));
        AionAddress usr3 = new AionAddress(Helpers.hexStringToBytes("3333333333333333333333333333333333333333333333333333333333333333"));
        AionAddress usr4 = new AionAddress(Helpers.hexStringToBytes("4444444444444444444444444444444444444444444444444444444444444444"));
        Transaction t0 = AvmTransactionUtil.call(preminedAddress, usr1, BigInteger.ZERO, BigInteger.valueOf(5_000_000), new byte[0], 100000L, 1);
        Transaction t1 = AvmTransactionUtil.call(usr1, usr2, BigInteger.ZERO, BigInteger.valueOf(4_000_000), new byte[0], 100000L, 1);
        Transaction t2 = AvmTransactionUtil.call(usr2, usr3, BigInteger.ZERO, BigInteger.valueOf(3_000_000), new byte[0], 100000L, 1);
        Transaction t3 = AvmTransactionUtil.call(usr3, usr4, BigInteger.ZERO, BigInteger.valueOf(2_000_000), new byte[0], 100000L, 1);
        Transaction t4 = AvmTransactionUtil.call(usr4, usr1, BigInteger.ZERO, BigInteger.valueOf(1_000_000), new byte[0], 100000L, 1);
        Transaction[] batch = new Transaction[] { t0, t1, t2, t3, t4 };
        FutureResult[] results = avm.run(kernel, batch, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1);
        for (FutureResult f : results) {
            f.getResult();
        }
        avm.shutdown();
    }

    @Test
    public void internalTransactionTest() {
        byte[] code = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(TestContract.clreplaced);
        TestingState kernel = new TestingState(block);
        AvmImpl avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
        AionAddress usr1 = new AionAddress(Helpers.hexStringToBytes("1111111111111111111111111111111111111111111111111111111111111111"));
        AionAddress usr2 = new AionAddress(Helpers.hexStringToBytes("2222222222222222222222222222222222222222222222222222222222222222"));
        AionAddress usr3 = new AionAddress(Helpers.hexStringToBytes("3333333333333333333333333333333333333333333333333333333333333333"));
        AionAddress usr4 = new AionAddress(Helpers.hexStringToBytes("4444444444444444444444444444444444444444444444444444444444444444"));
        Transaction t0 = AvmTransactionUtil.call(preminedAddress, usr1, BigInteger.ZERO, BigInteger.valueOf(5_000_000), new byte[0], 100000L, 1);
        Transaction t1 = AvmTransactionUtil.call(preminedAddress, usr2, BigInteger.ONE, BigInteger.valueOf(5_000_000), new byte[0], 100000L, 1);
        Transaction t2 = AvmTransactionUtil.call(preminedAddress, usr3, BigInteger.TWO, BigInteger.valueOf(5_000_000), new byte[0], 100000L, 1);
        Transaction t3 = AvmTransactionUtil.call(preminedAddress, usr4, BigInteger.valueOf(3), BigInteger.valueOf(15_000_000), new byte[0], 100000L, 1);
        Transaction t4 = AvmTransactionUtil.create(usr4, BigInteger.ZERO, BigInteger.ZERO, new CodeAndArguments(code, null).encodeToBytes(), 10_000_000L, 1);
        Transaction[] batch = new Transaction[] { t0, t1, t2, t3, t4 };
        FutureResult[] results = avm.run(kernel, batch, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1);
        for (FutureResult f : results) {
            f.getResult();
        }
        TransactionResult res = results[4].getResult();
        AionAddress contractAddr = new AionAddress(res.copyOfTransactionOutput().orElseThrow());
        byte[] args = encodeNoArgsMethodCall("doTransfer");
        byte[] args2 = encodeNoArgsMethodCall("addValue");
        t0 = AvmTransactionUtil.call(preminedAddress, contractAddr, BigInteger.valueOf(4), BigInteger.valueOf(5_000_000), args2, 100000L, 1);
        t1 = AvmTransactionUtil.call(usr1, contractAddr, BigInteger.ZERO, BigInteger.ZERO, args, 200000L, 1);
        t2 = AvmTransactionUtil.call(usr2, contractAddr, BigInteger.ZERO, BigInteger.ZERO, args, 200000L, 1);
        t3 = AvmTransactionUtil.call(usr3, contractAddr, BigInteger.ZERO, BigInteger.ZERO, args, 200000L, 1);
        t4 = AvmTransactionUtil.call(usr4, contractAddr, BigInteger.ONE, BigInteger.ZERO, args, 200000L, 1);
        batch = new Transaction[] { t0, t1, t2, t3, t4 };
        results = avm.run(kernel, batch, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1);
        for (FutureResult f : results) {
            f.getResult();
        }
        avm.shutdown();
    }

    /**
     * This test attempts to transfer to 100 users and then from those to 1 user.  This will cause heavy abort behaviour because this is a data hazard.
     */
    @Test
    public void heavyAbortTest() {
        TestingState kernel = new TestingState(block);
        AvmImpl avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
        // We will send 2x the value to these accounts, initially, and they will send 1x to the target.
        int iterations = 100;
        long valueToSend = 1_000_000L;
        AionAddress targetUser = Helpers.randomAddress();
        AionAddress[] tempUsers = new AionAddress[iterations];
        // First batch - disperse funds.
        Transaction[] firstBatch = new Transaction[iterations];
        for (int i = 0; i < iterations; ++i) {
            tempUsers[i] = Helpers.randomAddress();
            firstBatch[i] = AvmTransactionUtil.call(preminedAddress, tempUsers[i], BigInteger.valueOf(i), BigInteger.valueOf(2L * valueToSend), new byte[0], 100_000L, 1L);
        }
        FutureResult[] results = avm.run(kernel, firstBatch, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1);
        for (FutureResult f : results) {
            replacedert.replacedertTrue(f.getResult().transactionStatus.isSuccess());
        }
        // Second batch - collect funds.
        Transaction[] secondBatch = new Transaction[iterations];
        for (int i = 0; i < iterations; ++i) {
            secondBatch[i] = AvmTransactionUtil.call(tempUsers[i], targetUser, BigInteger.ZERO, BigInteger.valueOf(valueToSend), new byte[0], 100_000L, 1L);
        }
        results = avm.run(kernel, secondBatch, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1);
        for (FutureResult f : results) {
            replacedert.replacedertTrue(f.getResult().transactionStatus.isSuccess());
        }
        // Check that this had the expected result.
        replacedert.replacedertEquals(BigInteger.valueOf((long) iterations * valueToSend), kernel.getBalance(targetUser));
        avm.shutdown();
    }

    @Test
    public void reentrantAbort() {
        byte[] code = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(TestContract.clreplaced);
        TestingState kernel = new TestingState(block);
        AvmImpl avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
        int length = 5;
        AionAddress[] user = new AionAddress[length];
        Transaction[] ctx = new Transaction[length];
        for (int i = 0; i < user.length; i++) {
            user[i] = Helpers.randomAddress();
            kernel.adjustBalance(user[i], BigInteger.TEN.pow(20));
            ctx[i] = AvmTransactionUtil.create(user[i], BigInteger.ZERO, BigInteger.ZERO, new CodeAndArguments(code, null).encodeToBytes(), 5_000_000L, 1);
        }
        FutureResult[] results = avm.run(kernel, ctx, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1);
        AionAddress[] contractAddresses = new AionAddress[results.length];
        for (int i = 0; i < results.length; i++) {
            contractAddresses[i] = new AionAddress(results[i].getResult().copyOfTransactionOutput().orElseThrow());
        }
        Transaction[] tx = new Transaction[results.length - 1];
        // A->A->B, B->B->C, C->C->D
        for (int i = 0; i < results.length - 1; i++) {
            byte[] internalCallData = new ABIStreamingEncoder().encodeOneString("doCallOther").encodeOneAddress(new Address(contractAddresses[i + 1].toByteArray())).encodeOneByteArray(new ABIStreamingEncoder().encodeOneString("addValue").toBytes()).toBytes();
            byte[] data = new ABIStreamingEncoder().encodeOneString("doCallThis").encodeOneByteArray(internalCallData).toBytes();
            tx[i] = AvmTransactionUtil.call(user[i], contractAddresses[i], kernel.getNonce(user[i]), BigInteger.ZERO, data, 5_000_000, 1);
        }
        results = avm.run(kernel, tx, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1);
        for (FutureResult f : results) {
            f.getResult();
        }
        // validate the state of contracts
        for (int i = 0; i < length - 1; i++) {
            byte[] getCallCount = new ABIStreamingEncoder().encodeOneString("getCallCount").toBytes();
            tx[i] = AvmTransactionUtil.call(user[i], contractAddresses[i], kernel.getNonce(user[i]), BigInteger.ZERO, getCallCount, 5_000_000, 1);
        }
        results = avm.run(kernel, tx, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1);
        for (FutureResult f : results) {
            replacedert.replacedertEquals(2, new ABIDecoder(f.getResult().copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        }
        for (int i = 1; i < length - 1; i++) {
            byte[] getValue = new ABIStreamingEncoder().encodeOneString("getValue").toBytes();
            tx[i] = AvmTransactionUtil.call(user[i], contractAddresses[i], kernel.getNonce(user[i]), BigInteger.ZERO, getValue, 5_000_000, 1);
        }
        results = avm.run(kernel, new Transaction[] { tx[1], tx[2], tx[3] }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1);
        for (FutureResult f : results) {
            replacedert.replacedertEquals(1, new ABIDecoder(f.getResult().copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        }
        avm.shutdown();
    }

    @Test
    public void internalTransactionAbort() {
        byte[] code = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(TestContract.clreplaced);
        TestingState kernel = new TestingState(block);
        AvmImpl avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
        int length = 4;
        AionAddress[] user = new AionAddress[length];
        Transaction[] ctx = new Transaction[length];
        for (int i = 0; i < length; i++) {
            user[i] = Helpers.randomAddress();
            kernel.adjustBalance(user[i], BigInteger.TEN.pow(20));
            ctx[i] = AvmTransactionUtil.create(user[i], BigInteger.ZERO, BigInteger.ZERO, new CodeAndArguments(code, null).encodeToBytes(), 5_000_000L, 1);
        }
        FutureResult[] results = avm.run(kernel, ctx, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1);
        AionAddress[] contractAddresses = new AionAddress[results.length];
        for (int i = 0; i < results.length; i++) {
            contractAddresses[i] = new AionAddress(results[i].getResult().copyOfTransactionOutput().orElseThrow());
        }
        Transaction[] tx = new Transaction[results.length - 1];
        // u1->A->B, u2->B->C, u3->C->D
        for (int i = 0; i < results.length - 1; i++) {
            byte[] callData = new ABIStreamingEncoder().encodeOneString("doCallOther").encodeOneAddress(new Address(contractAddresses[i + 1].toByteArray())).encodeOneByteArray(new ABIStreamingEncoder().encodeOneString("addValue").toBytes()).toBytes();
            tx[i] = AvmTransactionUtil.call(user[i], contractAddresses[i], kernel.getNonce(user[i]), BigInteger.ZERO, callData, 5_000_000, 1);
        }
        results = avm.run(kernel, tx, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1);
        for (FutureResult f : results) {
            f.getResult();
        }
        // validate the state of contracts
        for (int i = 0; i < length - 1; i++) {
            byte[] getCallCount = new ABIStreamingEncoder().encodeOneString("getCallCount").toBytes();
            tx[i] = AvmTransactionUtil.call(user[i], contractAddresses[i], kernel.getNonce(user[i]), BigInteger.ZERO, getCallCount, 5_000_000, 1);
        }
        results = avm.run(kernel, tx, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1);
        for (FutureResult f : results) {
            replacedert.replacedertEquals(1, new ABIDecoder(f.getResult().copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        }
        for (int i = 1; i < length - 1; i++) {
            byte[] getValue = new ABIStreamingEncoder().encodeOneString("getValue").toBytes();
            tx[i] = AvmTransactionUtil.call(user[i], contractAddresses[i], kernel.getNonce(user[i]), BigInteger.ZERO, getValue, 5_000_000, 1);
        }
        Transaction[] batch = new Transaction[] { tx[1], tx[2] };
        results = avm.run(kernel, batch, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1);
        for (FutureResult f : results) {
            replacedert.replacedertEquals(1, new ABIDecoder(f.getResult().copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        }
        avm.shutdown();
    }

    @Test
    public void internalTransactionAbortDuringTransformation() {
        byte[] code = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(TestContract.clreplaced);
        TestingState kernel = new TestingState(block);
        AvmImpl avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
        int length = 4;
        AionAddress[] user = new AionAddress[length];
        Transaction[] ctx = new Transaction[length];
        for (int i = 0; i < length; i++) {
            user[i] = Helpers.randomAddress();
            kernel.adjustBalance(user[i], BigInteger.TEN.pow(20));
            ctx[i] = AvmTransactionUtil.create(user[i], BigInteger.ZERO, BigInteger.ZERO, new CodeAndArguments(code, null).encodeToBytes(), 5_000_000L, 1);
        }
        FutureResult[] results = avm.run(kernel, ctx, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1);
        AionAddress[] contractAddresses = new AionAddress[results.length];
        for (int i = 0; i < results.length; i++) {
            contractAddresses[i] = new AionAddress(results[i].getResult().copyOfTransactionOutput().orElseThrow());
            kernel.setTransformedCode(contractAddresses[i], null);
        }
        Transaction[] tx = new Transaction[results.length - 1];
        // u1->A->B, u2->B->C, u3->C->D
        for (int i = 0; i < results.length - 1; i++) {
            byte[] callData = new ABIStreamingEncoder().encodeOneString("doCallOther").encodeOneAddress(new Address(contractAddresses[i + 1].toByteArray())).encodeOneByteArray(new ABIStreamingEncoder().encodeOneString("addValue").toBytes()).toBytes();
            tx[i] = AvmTransactionUtil.call(user[i], contractAddresses[i], kernel.getNonce(user[i]), BigInteger.ZERO, callData, 5_000_000, 1);
        }
        for (AionAddress contractAddress : contractAddresses) {
            kernel.setTransformedCode(contractAddress, null);
        }
        results = avm.run(kernel, tx, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1);
        for (FutureResult f : results) {
            f.getResult();
        }
        // validate the state of contracts
        for (int i = 0; i < length - 1; i++) {
            byte[] getCallCount = new ABIStreamingEncoder().encodeOneString("getCallCount").toBytes();
            tx[i] = AvmTransactionUtil.call(user[i], contractAddresses[i], kernel.getNonce(user[i]), BigInteger.ZERO, getCallCount, 5_000_000, 1);
        }
        results = avm.run(kernel, tx, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1);
        for (FutureResult f : results) {
            replacedert.replacedertEquals(1, new ABIDecoder(f.getResult().copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        }
        avm.shutdown();
    }

    @Test
    public void testCoinbaseLock() {
        byte[] code = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(TestContract.clreplaced);
        TestingState kernel = new TestingState(block);
        AvmImpl avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
        int length = 3;
        AionAddress[] user = new AionAddress[length];
        Transaction[] ctx = new Transaction[length];
        for (int i = 0; i < length; i++) {
            user[i] = Helpers.randomAddress();
            kernel.adjustBalance(user[i], BigInteger.TEN.pow(20));
            ctx[i] = AvmTransactionUtil.create(user[i], BigInteger.ZERO, BigInteger.ZERO, new CodeAndArguments(code, null).encodeToBytes(), 5_000_000L, 1);
        }
        FutureResult[] results = avm.run(kernel, ctx, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1);
        AionAddress[] contractAddresses = new AionAddress[results.length];
        for (int i = 0; i < results.length; i++) {
            contractAddresses[i] = new AionAddress(results[i].getResult().copyOfTransactionOutput().orElseThrow());
        }
        kernel.generateBlock();
        byte[][] callData = new byte[length][];
        Address minerAddress = new Address(kernel.getMinerAddress().toByteArray());
        callData[0] = new ABIStreamingEncoder().encodeOneString("getBalance").encodeOneAddress(new Address(Helpers.randomBytes(32))).encodeOneInteger(1000).toBytes();
        callData[1] = new ABIStreamingEncoder().encodeOneString("addValue").toBytes();
        callData[2] = new ABIStreamingEncoder().encodeOneString("getBalance").encodeOneAddress(minerAddress).encodeOneInteger(1000).toBytes();
        Transaction[] tx = new Transaction[length];
        for (int i = 0; i < length; i++) {
            tx[i] = AvmTransactionUtil.call(user[i], contractAddresses[i], kernel.getNonce(user[i]), BigInteger.ZERO, callData[i], 10_000_000, 1);
        }
        BigInteger initialBalance = kernel.getBalance(kernel.getMinerAddress());
        // Specifically tests the issue mentioned in AKI-644
        results = avm.run(kernel, tx, ExecutionType.MINING, kernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(BigInteger.ZERO, new ABIDecoder(results[0].getResult().copyOfTransactionOutput().orElseThrow()).decodeOneBigInteger());
        replacedert.replacedertEquals(initialBalance.add(BigInteger.valueOf(results[0].getResult().energyUsed)).add(BigInteger.valueOf(results[1].getResult().energyUsed)), new ABIDecoder(results[2].getResult().copyOfTransactionOutput().orElseThrow()).decodeOneBigInteger());
        avm.shutdown();
    }

    private static byte[] encodeNoArgsMethodCall(String methodName) {
        return new ABIStreamingEncoder().encodeOneString(methodName).toBytes();
    }
}

19 Source : Blake2bTest.java
with MIT License
from aionnetwork

public clreplaced Blake2bTest {

    private long energyLimit = 10_000_000L;

    private long energyPrice = 1L;

    private AionAddress deployer = TestingState.PREMINED_ADDRESS;

    private AionAddress dappAddress;

    private TestingState kernel;

    private AvmImpl avm;

    @Before
    public void setup() {
        TestingBlock block = new TestingBlock(new byte[32], 1, Helpers.randomAddress(), System.currentTimeMillis(), new byte[0]);
        this.kernel = new TestingState(block);
        this.avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
        byte[] jar = JarBuilder.buildJarForMainClreplacedAndExplicitClreplacedNamesAndBytecode(Main.clreplaced, Collections.emptyMap(), Blake2b.clreplaced);
        byte[] arguments = null;
        Transaction tx = AvmTransactionUtil.create(deployer, kernel.getNonce(deployer), BigInteger.ZERO, new CodeAndArguments(jar, arguments).encodeToBytes(), energyLimit, energyPrice);
        TransactionResult txResult = avm.run(this.kernel, new Transaction[] { tx }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
        replacedert.replacedertTrue(txResult.transactionStatus.isSuccess());
        dappAddress = new AionAddress(txResult.copyOfTransactionOutput().orElseThrow());
        replacedertNotNull(dappAddress);
    }

    @After
    public void tearDown() {
        this.avm.shutdown();
    }

    @Test
    public void testBlake2b() {
        Blake2b mac = Blake2b.Mac.newInstance("key".getBytes());
        byte[] hash = mac.digest("input".getBytes());
        Transaction tx = AvmTransactionUtil.call(deployer, dappAddress, kernel.getNonce(deployer), BigInteger.ZERO, new byte[0], energyLimit, energyPrice);
        TransactionResult txResult = avm.run(this.kernel, new Transaction[] { tx }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
        replacedert.replacedertTrue(txResult.transactionStatus.isSuccess());
        replacedertArrayEquals(hash, txResult.copyOfTransactionOutput().orElseThrow());
    }
}

19 Source : FunctionShadowTest.java
with MIT License
from aionnetwork

public clreplaced FunctionShadowTest {

    private static final long ENERGY_LIMIT = 6_000_000L;

    private static final long ERNGY_PRICE = 1L;

    private static final AionAddress FROM = TestingState.PREMINED_ADDRESS;

    private static TestingState kernel;

    private static AvmImpl avm;

    @BeforeClreplaced
    public static void setup() {
        TestingBlock block = new TestingBlock(new byte[32], 1, Helpers.randomAddress(), System.currentTimeMillis(), new byte[0]);
        kernel = new TestingState(block);
        AvmConfiguration config = new AvmConfiguration();
        config.preserveDebuggability = true;
        avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), config);
    }

    @AfterClreplaced
    public static void tearDown() {
        avm.shutdown();
    }

    @Test
    public void testNonWhitelistFunction() {
        Clreplaced<?> testClreplaced = FunctionShadowFailSupplierResource.clreplaced;
        AionAddress dappAddr = deployTest(testClreplaced);
        // We expect a deployment failure.
        replacedert.replacedertNull(dappAddr);
    }

    @Test
    public void testParameterFunction() {
        Clreplaced<?> testClreplaced = FunctionShadowFailArgsResource.clreplaced;
        AionAddress dappAddr = deployTest(testClreplaced);
        // We expect a deployment failure.
        replacedert.replacedertNull(dappAddr);
    }

    @Test
    public void testSafeParameterFunction() {
        Clreplaced<?> testClreplaced = FunctionShadowPreplacedArgsResource.clreplaced;
        AionAddress dappAddr = deployTest(testClreplaced);
        // This case should succeed.
        replacedert.replacedertNotNull(dappAddr);
    }

    @Test
    public void testNoComparableFunction() {
        Clreplaced<?> testClreplaced = FunctionShadowFailComparableResource.clreplaced;
        AionAddress dappAddr = deployTest(testClreplaced);
        // We expect a deployment failure.
        replacedert.replacedertNull(dappAddr);
    }

    @Test
    public void testLambdaRunnable() {
        // deploy it
        Clreplaced<?> testClreplaced = FunctionShadowResource.clreplaced;
        AionAddress dappAddr = deployTest(testClreplaced);
        // call transactions and validate the results
        oneCall(dappAddr, 0);
    }

    @Test
    public void testLambdaFunction() {
        // deploy it
        Clreplaced<?> testClreplaced = FunctionShadowResource.clreplaced;
        AionAddress dappAddr = deployTest(testClreplaced);
        // call transactions and validate the results
        oneCall(dappAddr, 1);
    }

    @Test
    public void testSerializedLambdaRunnable() {
        // deploy it
        Clreplaced<?> testClreplaced = FunctionShadowResource.clreplaced;
        AionAddress dappAddr = deployTest(testClreplaced);
        // Call the setup routine (2)
        oneCall(dappAddr, 2);
        // Call the check routine (3)
        oneCall(dappAddr, 3);
    }

    @Test
    public void testSerializedLambdaFunction() {
        // deploy it
        Clreplaced<?> testClreplaced = FunctionShadowResource.clreplaced;
        AionAddress dappAddr = deployTest(testClreplaced);
        // Call the setup routine (4)
        oneCall(dappAddr, 4);
        // Call the check routine (5)
        oneCall(dappAddr, 5);
    }

    @Test
    public void testReferenceFunction() {
        // deploy it
        Clreplaced<?> testClreplaced = FunctionShadowResource.clreplaced;
        AionAddress dappAddr = deployTest(testClreplaced);
        // call transactions and validate the results
        oneCall(dappAddr, 6);
    }

    @Test
    public void testNonSharedLambdas() {
        // deploy it
        Clreplaced<?> testClreplaced = FunctionShadowResource.clreplaced;
        AionAddress dappAddr = deployTest(testClreplaced);
        // call transactions and validate the results
        oneCall(dappAddr, 7);
    }

    @Test
    public void testExceptionInLambdas() {
        // deploy it
        Clreplaced<?> testClreplaced = FunctionShadowResource.clreplaced;
        AionAddress dappAddr = deployTest(testClreplaced);
        // call transactions and validate the results
        oneCall(dappAddr, 8);
    }

    private AionAddress deployTest(Clreplaced<?> testClreplaced) {
        byte[] testJar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(testClreplaced);
        byte[] txData = new CodeAndArguments(testJar, null).encodeToBytes();
        Transaction tx = AvmTransactionUtil.create(FROM, kernel.getNonce(FROM), BigInteger.ZERO, txData, ENERGY_LIMIT, ERNGY_PRICE);
        Optional<byte[]> optionalOutput = avm.run(kernel, new Transaction[] { tx }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult().copyOfTransactionOutput();
        return (optionalOutput.isPresent()) ? new AionAddress(optionalOutput.get()) : null;
    }

    private void oneCall(AionAddress dappAddr, int transactionNumber) {
        Transaction tx = AvmTransactionUtil.call(FROM, dappAddr, kernel.getNonce(FROM), BigInteger.ZERO, new byte[] { (byte) transactionNumber }, ENERGY_LIMIT, ERNGY_PRICE);
        TransactionResult result = avm.run(kernel, new Transaction[] { tx }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
        replacedert.replacedertTrue(result.transactionStatus.isSuccess());
    }
}

19 Source : FunctionShadowTest.java
with MIT License
from aionnetwork

@Test
public void testNoComparableFunction() {
    Clreplaced<?> testClreplaced = FunctionShadowFailComparableResource.clreplaced;
    AionAddress dappAddr = deployTest(testClreplaced);
    // We expect a deployment failure.
    replacedert.replacedertNull(dappAddr);
}

19 Source : FunctionShadowTest.java
with MIT License
from aionnetwork

@Test
public void testParameterFunction() {
    Clreplaced<?> testClreplaced = FunctionShadowFailArgsResource.clreplaced;
    AionAddress dappAddr = deployTest(testClreplaced);
    // We expect a deployment failure.
    replacedert.replacedertNull(dappAddr);
}

19 Source : FunctionShadowTest.java
with MIT License
from aionnetwork

@Test
public void testExceptionInLambdas() {
    // deploy it
    Clreplaced<?> testClreplaced = FunctionShadowResource.clreplaced;
    AionAddress dappAddr = deployTest(testClreplaced);
    // call transactions and validate the results
    oneCall(dappAddr, 8);
}

19 Source : FunctionShadowTest.java
with MIT License
from aionnetwork

@Test
public void testNonSharedLambdas() {
    // deploy it
    Clreplaced<?> testClreplaced = FunctionShadowResource.clreplaced;
    AionAddress dappAddr = deployTest(testClreplaced);
    // call transactions and validate the results
    oneCall(dappAddr, 7);
}

19 Source : FunctionShadowTest.java
with MIT License
from aionnetwork

@Test
public void testReferenceFunction() {
    // deploy it
    Clreplaced<?> testClreplaced = FunctionShadowResource.clreplaced;
    AionAddress dappAddr = deployTest(testClreplaced);
    // call transactions and validate the results
    oneCall(dappAddr, 6);
}

19 Source : FunctionShadowTest.java
with MIT License
from aionnetwork

@Test
public void testNonWhitelistFunction() {
    Clreplaced<?> testClreplaced = FunctionShadowFailSupplierResource.clreplaced;
    AionAddress dappAddr = deployTest(testClreplaced);
    // We expect a deployment failure.
    replacedert.replacedertNull(dappAddr);
}

19 Source : FunctionShadowTest.java
with MIT License
from aionnetwork

@Test
public void testSerializedLambdaFunction() {
    // deploy it
    Clreplaced<?> testClreplaced = FunctionShadowResource.clreplaced;
    AionAddress dappAddr = deployTest(testClreplaced);
    // Call the setup routine (4)
    oneCall(dappAddr, 4);
    // Call the check routine (5)
    oneCall(dappAddr, 5);
}

19 Source : FunctionShadowTest.java
with MIT License
from aionnetwork

@Test
public void testSafeParameterFunction() {
    Clreplaced<?> testClreplaced = FunctionShadowPreplacedArgsResource.clreplaced;
    AionAddress dappAddr = deployTest(testClreplaced);
    // This case should succeed.
    replacedert.replacedertNotNull(dappAddr);
}

19 Source : FunctionShadowTest.java
with MIT License
from aionnetwork

@Test
public void testLambdaRunnable() {
    // deploy it
    Clreplaced<?> testClreplaced = FunctionShadowResource.clreplaced;
    AionAddress dappAddr = deployTest(testClreplaced);
    // call transactions and validate the results
    oneCall(dappAddr, 0);
}

19 Source : FunctionShadowTest.java
with MIT License
from aionnetwork

@Test
public void testSerializedLambdaRunnable() {
    // deploy it
    Clreplaced<?> testClreplaced = FunctionShadowResource.clreplaced;
    AionAddress dappAddr = deployTest(testClreplaced);
    // Call the setup routine (2)
    oneCall(dappAddr, 2);
    // Call the check routine (3)
    oneCall(dappAddr, 3);
}

19 Source : FunctionShadowTest.java
with MIT License
from aionnetwork

@Test
public void testLambdaFunction() {
    // deploy it
    Clreplaced<?> testClreplaced = FunctionShadowResource.clreplaced;
    AionAddress dappAddr = deployTest(testClreplaced);
    // call transactions and validate the results
    oneCall(dappAddr, 1);
}

19 Source : DefaultMethodIntegrationTest.java
with MIT License
from aionnetwork

/**
 * Tests that we fail in a meaningful way when a DApp throws an exception due to a missing method.
 */
public clreplaced DefaultMethodIntegrationTest {

    private static AionAddress deployer = TestingState.PREMINED_ADDRESS;

    private static TestingState kernel;

    private static AvmImpl avm;

    @BeforeClreplaced
    public static void setup() {
        TestingBlock block = new TestingBlock(new byte[32], 1, Helpers.randomAddress(), System.currentTimeMillis(), new byte[0]);
        kernel = new TestingState(block);
        avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
    }

    @AfterClreplaced
    public static void tearDown() {
        avm.shutdown();
    }

    @Test
    public void testMissingDefaultInClinit() throws Exception {
        byte[] jar = JarBuilder.buildJarForMainClreplacedAndExplicitClreplacedNamesAndBytecode(TestDefaultMethodInClinitResource.clreplaced, Collections.emptyMap(), AionMap.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        // Deploy.
        long energyLimit = 2_000_000l;
        long energyPrice = 1l;
        Transaction create = AvmTransactionUtil.create(deployer, kernel.getNonce(deployer), BigInteger.ZERO, txData, energyLimit, energyPrice);
        // The NoSuchMethodError triggers a "FAILED_EXCEPTION" state.
        TransactionResult result = avm.run(kernel, new Transaction[] { create }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
        replacedert.replacedertEquals(AvmInternalError.FAILED_EXCEPTION.error, result.transactionStatus.causeOfError);
    }

    @Test
    public void testMissingDefaultInMain() throws Exception {
        byte[] jar = JarBuilder.buildJarForMainClreplacedAndExplicitClreplacedNamesAndBytecode(TestDefaultMethodInMainResource.clreplaced, Collections.emptyMap(), AionMap.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        // Deploy.
        long energyLimit = 2_000_000l;
        long energyPrice = 1l;
        Transaction create = AvmTransactionUtil.create(deployer, kernel.getNonce(deployer), BigInteger.ZERO, txData, energyLimit, energyPrice);
        TransactionResult createResult = avm.run(kernel, new Transaction[] { create }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
        replacedert.replacedertTrue(createResult.transactionStatus.isSuccess());
        AionAddress contractAddr = new AionAddress(createResult.copyOfTransactionOutput().orElseThrow());
        // Setup the call (parameters are currently ignored).
        byte[] argData = new byte[0];
        Transaction call = AvmTransactionUtil.call(deployer, contractAddr, kernel.getNonce(deployer), BigInteger.ZERO, argData, energyLimit, 1l);
        // The NoSuchMethodError triggers a "FAILED_EXCEPTION" state.
        TransactionResult result = avm.run(kernel, new Transaction[] { call }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
        replacedert.replacedertEquals(AvmInternalError.FAILED_EXCEPTION.error, result.transactionStatus.causeOfError);
    }
}

19 Source : ResultTest.java
with MIT License
from aionnetwork

private static byte[] encodeForTransfer(AionAddress target, byte[] data) {
    return new ABIStreamingEncoder().encodeOneString("testTransfer").encodeOneAddress(new Address(target.toByteArray())).encodeOneByteArray(data).toBytes();
}

19 Source : ResultTest.java
with MIT License
from aionnetwork

private static byte[] encodeForCall(AionAddress target, byte[] data, boolean expectToPreplaced) {
    return new ABIStreamingEncoder().encodeOneString("testCall").encodeOneAddress(new Address(target.toByteArray())).encodeOneByteArray(data).encodeOneBoolean(expectToPreplaced).toBytes();
}

19 Source : RejectVirtualMachineErrorIntegrationTest.java
with MIT License
from aionnetwork

/**
 * Implemented as part of issue-303 to demonstrate that user code is not able to catch, throw, sub-clreplaced, or even instantiate any
 * java.lang.VirtualMachineError type.
 * Since the rejection will be made at the clreplaced level, we need several test clreplacedes.
 *
 * We need to run these as integration tests since, although many are just testing the rejection phase, some have runtime considerations
 * since Throwable can be caught, but none of the VirtualMachineError instances should actually appear there.
 */
public clreplaced RejectVirtualMachineErrorIntegrationTest {

    private static AionAddress FROM = TestingState.PREMINED_ADDRESS;

    private static long ENERGY_LIMIT = 5_000_000L;

    private static long ENERGY_PRICE = 1L;

    private static IExternalState externalState;

    private static AvmImpl avm;

    @BeforeClreplaced
    public static void setup() {
        TestingBlock BLOCK = new TestingBlock(new byte[32], 1, Helpers.randomAddress(), System.currentTimeMillis(), new byte[0]);
        externalState = new TestingState(BLOCK);
        avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
    }

    @AfterClreplaced
    public static void tearDown() {
        avm.shutdown();
    }

    @Test
    public void rejectCatchError() throws Exception {
        byte[] jar = JarBuilder.buildJarForMainClreplacedAndExplicitClreplacedNamesAndBytecode(RejectCatchError.clreplaced, Collections.emptyMap());
        // Deploy.
        TransactionResult createResult = deployJar(jar);
        replacedert.replacedertEquals(AvmInternalError.FAILED_REJECTED_CLreplaced.error, createResult.transactionStatus.causeOfError);
    }

    @Test
    public void rejectInstantiateError() throws Exception {
        byte[] jar = JarBuilder.buildJarForMainClreplacedAndExplicitClreplacedNamesAndBytecode(RejectInstantiateError.clreplaced, Collections.emptyMap());
        // Deploy.
        TransactionResult createResult = deployJar(jar);
        replacedert.replacedertEquals(AvmInternalError.FAILED_REJECTED_CLreplaced.error, createResult.transactionStatus.causeOfError);
    }

    @Test
    public void rejectSubclreplacedError() throws Exception {
        byte[] jar = JarBuilder.buildJarForMainClreplacedAndExplicitClreplacedNamesAndBytecode(RejectSubclreplacedError.clreplaced, Collections.emptyMap());
        // Deploy.
        TransactionResult createResult = deployJar(jar);
        replacedert.replacedertEquals(AvmInternalError.FAILED_REJECTED_CLreplaced.error, createResult.transactionStatus.causeOfError);
    }

    private TransactionResult deployJar(byte[] jar) {
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        Transaction transaction = AvmTransactionUtil.create(FROM, externalState.getNonce(FROM), BigInteger.ZERO, txData, ENERGY_LIMIT, ENERGY_PRICE);
        return avm.run(RejectVirtualMachineErrorIntegrationTest.externalState, new Transaction[] { transaction }, ExecutionType.replacedUME_MAINCHAIN, externalState.getBlockNumber() - 1)[0].getResult();
    }
}

19 Source : ClassShapeRuleTest.java
with MIT License
from aionnetwork

public clreplaced ClreplacedShapeRuleTest {

    private static AionAddress DEPLOYER = TestingState.PREMINED_ADDRESS;

    private static TestingBlock BLOCK = new TestingBlock(new byte[32], 1, Helpers.randomAddress(), System.currentTimeMillis(), new byte[0]);

    @Test
    public void testLimitNoop() throws Exception {
        String clreplacedName = "ClreplacedName";
        byte[] clreplacedBytes = createNoopClreplaced(clreplacedName, ConsensusLimitConstants.MAX_METHOD_BYTE_LENGTH);
        boolean didDeploy = deployOnAvm(clreplacedName, clreplacedBytes);
        replacedert.replacedertTrue(didDeploy);
    }

    @Test
    public void testLongNoop() throws Exception {
        String clreplacedName = "ClreplacedName";
        byte[] clreplacedBytes = createNoopClreplaced(clreplacedName, ConsensusLimitConstants.MAX_METHOD_BYTE_LENGTH + 1);
        boolean didDeploy = deployOnAvm(clreplacedName, clreplacedBytes);
        replacedert.replacedertFalse(didDeploy);
    }

    @Test
    public void testLimitCatch() throws Exception {
        String clreplacedName = "ClreplacedName";
        byte[] clreplacedBytes = createLongThrowClreplaced(clreplacedName, ConsensusLimitConstants.MAX_EXCEPTION_TABLE_ENTRIES);
        boolean didDeploy = deployOnAvm(clreplacedName, clreplacedBytes);
        replacedert.replacedertTrue(didDeploy);
    }

    @Test
    public void testDeepCatch() throws Exception {
        String clreplacedName = "ClreplacedName";
        byte[] clreplacedBytes = createLongThrowClreplaced(clreplacedName, ConsensusLimitConstants.MAX_EXCEPTION_TABLE_ENTRIES + 1);
        boolean didDeploy = deployOnAvm(clreplacedName, clreplacedBytes);
        replacedert.replacedertFalse(didDeploy);
    }

    @Test
    public void testLimitIntPush() throws Exception {
        String clreplacedName = "ClreplacedName";
        byte[] clreplacedBytes = createDeepPushClreplaced(clreplacedName, ConsensusLimitConstants.MAX_OPERAND_STACK_DEPTH, false);
        boolean didDeploy = deployOnAvm(clreplacedName, clreplacedBytes);
        replacedert.replacedertTrue(didDeploy);
    }

    @Test
    public void testDeepIntPush() throws Exception {
        String clreplacedName = "ClreplacedName";
        byte[] clreplacedBytes = createDeepPushClreplaced(clreplacedName, ConsensusLimitConstants.MAX_OPERAND_STACK_DEPTH + 1, false);
        boolean didDeploy = deployOnAvm(clreplacedName, clreplacedBytes);
        replacedert.replacedertFalse(didDeploy);
    }

    @Test
    public void testLimitLongPush() throws Exception {
        String clreplacedName = "ClreplacedName";
        byte[] clreplacedBytes = createDeepPushClreplaced(clreplacedName, ceilingDivideByTwo(ConsensusLimitConstants.MAX_OPERAND_STACK_DEPTH), true);
        boolean didDeploy = deployOnAvm(clreplacedName, clreplacedBytes);
        replacedert.replacedertTrue(didDeploy);
    }

    @Test
    public void testDeepLongPush() throws Exception {
        String clreplacedName = "ClreplacedName";
        byte[] clreplacedBytes = createDeepPushClreplaced(clreplacedName, ceilingDivideByTwo(ConsensusLimitConstants.MAX_OPERAND_STACK_DEPTH) + 1, true);
        boolean didDeploy = deployOnAvm(clreplacedName, clreplacedBytes);
        replacedert.replacedertFalse(didDeploy);
    }

    @Test
    public void testLimitIntVars() throws Exception {
        String clreplacedName = "ClreplacedName";
        byte[] clreplacedBytes = createVarHeavyClreplaced(clreplacedName, ConsensusLimitConstants.MAX_LOCAL_VARIABLES, false);
        boolean didDeploy = deployOnAvm(clreplacedName, clreplacedBytes);
        replacedert.replacedertTrue(didDeploy);
    }

    @Test
    public void testFailIntVars() throws Exception {
        String clreplacedName = "ClreplacedName";
        byte[] clreplacedBytes = createVarHeavyClreplaced(clreplacedName, ConsensusLimitConstants.MAX_LOCAL_VARIABLES + 1, false);
        boolean didDeploy = deployOnAvm(clreplacedName, clreplacedBytes);
        replacedert.replacedertFalse(didDeploy);
    }

    @Test
    public void testLimitLongVars() throws Exception {
        String clreplacedName = "ClreplacedName";
        byte[] clreplacedBytes = createVarHeavyClreplaced(clreplacedName, ConsensusLimitConstants.MAX_LOCAL_VARIABLES - 1, true);
        boolean didDeploy = deployOnAvm(clreplacedName, clreplacedBytes);
        replacedert.replacedertTrue(didDeploy);
    }

    @Test
    public void testFailLongVars() throws Exception {
        String clreplacedName = "ClreplacedName";
        byte[] clreplacedBytes = createVarHeavyClreplaced(clreplacedName, ConsensusLimitConstants.MAX_LOCAL_VARIABLES, true);
        boolean didDeploy = deployOnAvm(clreplacedName, clreplacedBytes);
        replacedert.replacedertFalse(didDeploy);
    }

    @Test
    public void testLimitMethodCount() throws Exception {
        String clreplacedName = "ClreplacedName";
        byte[] clreplacedBytes = createMethodHeavyClreplaced(clreplacedName, ConsensusLimitConstants.MAX_METHOD_COUNT);
        boolean didDeploy = deployOnAvm(clreplacedName, clreplacedBytes);
        replacedert.replacedertTrue(didDeploy);
    }

    @Test
    public void testFailMethodCount() throws Exception {
        String clreplacedName = "ClreplacedName";
        byte[] clreplacedBytes = createMethodHeavyClreplaced(clreplacedName, ConsensusLimitConstants.MAX_METHOD_COUNT + 1);
        boolean didDeploy = deployOnAvm(clreplacedName, clreplacedBytes);
        replacedert.replacedertFalse(didDeploy);
    }

    @Test
    public void testLimitConstantPoolEntries() throws Exception {
        String clreplacedName = "ClreplacedName";
        byte[] clreplacedBytes = createConstantHeavyClreplaced(clreplacedName, ConsensusLimitConstants.MAX_CONSTANT_POOL_ENTRIES);
        boolean didDeploy = deployOnAvm(clreplacedName, clreplacedBytes);
        replacedert.replacedertTrue(didDeploy);
    }

    @Test
    public void testFailConstantPoolEntries() throws Exception {
        String clreplacedName = "ClreplacedName";
        byte[] clreplacedBytes = createConstantHeavyClreplaced(clreplacedName, ConsensusLimitConstants.MAX_CONSTANT_POOL_ENTRIES + 1);
        boolean didDeploy = deployOnAvm(clreplacedName, clreplacedBytes);
        replacedert.replacedertFalse(didDeploy);
    }

    private static byte[] createNoopClreplaced(String clreplacedName, int instructionCount) {
        ClreplacedWriter writer = new ClreplacedWriter(ClreplacedWriter.COMPUTE_FRAMES | ClreplacedWriter.COMPUTE_MAXS);
        writer.visit(Opcodes.V10, Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER, clreplacedName, null, "java/lang/Object", new String[0]);
        MethodVisitor method = writer.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "main", "()[B", null, null);
        for (int i = 0; i < (instructionCount - 2); ++i) {
            method.visitInsn(Opcodes.NOP);
        }
        method.visitInsn(Opcodes.ACONST_NULL);
        method.visitInsn(Opcodes.ARETURN);
        method.visitMaxs(0, 0);
        method.visitEnd();
        writer.visitEnd();
        return writer.toByteArray();
    }

    private static byte[] createLongThrowClreplaced(String clreplacedName, int catchDepth) {
        // Note that the way this test writes the method, catchDepth MUST be at least 1.
        replacedert.replacedertTrue(catchDepth >= 1);
        ClreplacedWriter writer = new ClreplacedWriter(ClreplacedWriter.COMPUTE_FRAMES | ClreplacedWriter.COMPUTE_MAXS);
        writer.visit(Opcodes.V10, Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER, clreplacedName, null, "java/lang/Object", new String[0]);
        // To test on filesystem, use "([Ljava/lang/String;)V".
        MethodVisitor method = writer.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "main", "()[B", null, null);
        Label start = new Label();
        Label end = new Label();
        Label handler = new Label();
        method.visitTryCatchBlock(start, end, handler, "java/lang/NullPointerException");
        method.visitLabel(start);
        method.visitInsn(Opcodes.ACONST_NULL);
        method.visitTypeInsn(Opcodes.CHECKCAST, "[Ljava/lang/Object;");
        method.visitInsn(Opcodes.ARRAYLENGTH);
        method.visitInsn(Opcodes.ACONST_NULL);
        method.visitInsn(Opcodes.ARETURN);
        method.visitLabel(end);
        for (int i = 0; i < (catchDepth - 1); ++i) {
            method.visitLabel(handler);
            start = new Label();
            end = new Label();
            handler = new Label();
            method.visitTryCatchBlock(start, end, handler, "java/lang/NullPointerException");
            method.visitLabel(start);
            method.visitInsn(Opcodes.ATHROW);
            method.visitLabel(end);
        }
        method.visitLabel(handler);
        method.visitInsn(Opcodes.ACONST_NULL);
        method.visitInsn(Opcodes.ARETURN);
        method.visitMaxs(0, 0);
        method.visitEnd();
        writer.visitEnd();
        return writer.toByteArray();
    }

    private static byte[] createDeepPushClreplaced(String clreplacedName, int pushCount, boolean isLong) {
        // Note that the setup for the method requires at least 2 stack depth.
        replacedert.replacedertTrue(pushCount >= 2);
        ClreplacedWriter writer = new ClreplacedWriter(ClreplacedWriter.COMPUTE_FRAMES | ClreplacedWriter.COMPUTE_MAXS);
        writer.visit(Opcodes.V10, Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER, clreplacedName, null, "java/lang/Object", new String[0]);
        MethodVisitor method = writer.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "main", "()[B", null, null);
        Object oneLong = Long.valueOf(1L);
        Object oneInt = Integer.valueOf(1);
        Object value = isLong ? oneLong : oneInt;
        // visitLdcInsn uses a type check so make sure that we got the type we were expecting (some compilers try to get clever here).
        if (isLong) {
            replacedert.replacedertTrue(value instanceof Long);
        } else {
            replacedert.replacedertTrue(value instanceof Integer);
        }
        method.visitLdcInsn(value);
        int storeOpcode = isLong ? Opcodes.LSTORE : Opcodes.ISTORE;
        method.visitVarInsn(storeOpcode, 0);
        int loadOpcode = isLong ? Opcodes.LLOAD : Opcodes.ILOAD;
        // Reduce the push count by 1 since we have at least one more slot for the return value.
        for (int i = 0; i < (pushCount - 1); ++i) {
            method.visitVarInsn(loadOpcode, 0);
        }
        method.visitInsn(Opcodes.ACONST_NULL);
        method.visitInsn(Opcodes.ARETURN);
        method.visitMaxs(0, 0);
        method.visitEnd();
        writer.visitEnd();
        return writer.toByteArray();
    }

    private static byte[] createVarHeavyClreplaced(String clreplacedName, int varCount, boolean isLong) {
        ClreplacedWriter writer = new ClreplacedWriter(ClreplacedWriter.COMPUTE_FRAMES | ClreplacedWriter.COMPUTE_MAXS);
        writer.visit(Opcodes.V10, Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER, clreplacedName, null, "java/lang/Object", new String[0]);
        MethodVisitor method = writer.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "main", "()[B", null, null);
        Object oneLong = Long.valueOf(1L);
        Object oneInt = Integer.valueOf(1);
        Object value = isLong ? oneLong : oneInt;
        int storeOpcode = isLong ? Opcodes.LSTORE : Opcodes.ISTORE;
        // visitLdcInsn uses a type check so make sure that we got the type we were expecting (some compilers try to get clever here).
        if (isLong) {
            replacedert.replacedertTrue(value instanceof Long);
        } else {
            replacedert.replacedertTrue(value instanceof Integer);
        }
        // Note that we will actually invalidate the local variable n-1 when writing a long, but this is just to verify that it reserves the next slot.
        for (int i = 0; i < varCount; ++i) {
            method.visitLdcInsn(value);
            method.visitVarInsn(storeOpcode, i);
        }
        method.visitInsn(Opcodes.ACONST_NULL);
        method.visitInsn(Opcodes.ARETURN);
        method.visitMaxs(0, 0);
        method.visitEnd();
        writer.visitEnd();
        return writer.toByteArray();
    }

    private static byte[] createMethodHeavyClreplaced(String clreplacedName, int methodCount) {
        // Note that the clreplaced will have the main so we need at least one method.
        replacedert.replacedertTrue(methodCount >= 1);
        String methodPrefix = "method_";
        String methodDescriptor = "()V";
        ClreplacedWriter writer = new ClreplacedWriter(ClreplacedWriter.COMPUTE_FRAMES | ClreplacedWriter.COMPUTE_MAXS);
        writer.visit(Opcodes.V10, Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER, clreplacedName, null, "java/lang/Object", new String[0]);
        MethodVisitor method = writer.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "main", "()[B", null, null);
        for (int i = 0; i < (methodCount - 1); ++i) {
            String methodName = methodPrefix + i;
            method.visitMethodInsn(Opcodes.INVOKESTATIC, clreplacedName, methodName, methodDescriptor, false);
        }
        method.visitInsn(Opcodes.ACONST_NULL);
        method.visitInsn(Opcodes.ARETURN);
        method.visitMaxs(0, 0);
        method.visitEnd();
        for (int i = 0; i < (methodCount - 1); ++i) {
            String methodName = methodPrefix + i;
            MethodVisitor targetMethod = writer.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, methodName, methodDescriptor, null, null);
            targetMethod.visitInsn(Opcodes.RETURN);
            targetMethod.visitMaxs(0, 0);
            targetMethod.visitEnd();
        }
        writer.visitEnd();
        return writer.toByteArray();
    }

    private static byte[] createConstantHeavyClreplaced(String clreplacedName, int constantCount) {
        ClreplacedWriter writer = new ClreplacedWriter(ClreplacedWriter.COMPUTE_FRAMES | ClreplacedWriter.COMPUTE_MAXS);
        writer.visit(Opcodes.V10, Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER, clreplacedName, null, "java/lang/Object", new String[0]);
        MethodVisitor method = writer.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "main", "()[B", null, null);
        // Note that we don't want to hit the method size limit so restrict this to 1000 constants per method.
        int constantsPerMethod = 1000;
        int methodCount = (constantCount + constantsPerMethod - 1) / constantsPerMethod;
        String methodPrefix = "method_";
        String methodDescriptor = "()V";
        // Note that the clreplaced will have constants for names, etc, so make sure we at least specify enough for that.
        // Specifically, there are 8 constants plus 3 per method generated.
        int baseConstantsAdded = 8 + (methodCount * 3);
        replacedert.replacedertTrue(constantCount >= baseConstantsAdded);
        int constantsToLoad = constantCount - baseConstantsAdded;
        for (int i = 0; i < methodCount; ++i) {
            String methodName = methodPrefix + i;
            method.visitMethodInsn(Opcodes.INVOKESTATIC, clreplacedName, methodName, methodDescriptor, false);
        }
        method.visitInsn(Opcodes.ACONST_NULL);
        method.visitInsn(Opcodes.ARETURN);
        method.visitMaxs(0, 0);
        method.visitEnd();
        int constantsCreated = 0;
        for (int i = 0; i < methodCount; ++i) {
            String methodName = methodPrefix + i;
            MethodVisitor targetMethod = writer.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, methodName, methodDescriptor, null, null);
            int constantsInMethod = Math.min((constantsToLoad - constantsCreated), constantsPerMethod);
            for (int j = 0; j < constantsInMethod; ++j) {
                targetMethod.visitLdcInsn(Integer.valueOf(constantsCreated + j));
                targetMethod.visitInsn(Opcodes.POP);
            }
            constantsCreated += constantsInMethod;
            targetMethod.visitInsn(Opcodes.RETURN);
            targetMethod.visitMaxs(0, 0);
            targetMethod.visitEnd();
        }
        writer.visitEnd();
        return writer.toByteArray();
    }

    private boolean deployOnAvm(String clreplacedName, byte[] clreplacedBytes) {
        byte[] jar = JarBuilder.buildJarForExplicitClreplacedNamesAndBytecode(clreplacedName, clreplacedBytes, Collections.emptyMap());
        byte[] deployment = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        TestingState kernel = new TestingState(BLOCK);
        AvmImpl avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
        long energyLimit = 5_000_000l;
        long energyPrice = 1l;
        Transaction deploymentTransaction = AvmTransactionUtil.create(DEPLOYER, kernel.getNonce(DEPLOYER), BigInteger.ZERO, deployment, energyLimit, energyPrice);
        TransactionResult deploymentResult = avm.run(kernel, new Transaction[] { deploymentTransaction }, ExecutionType.replacedUME_MAINCHAIN, 0)[0].getResult();
        boolean didDeploy = deploymentResult.transactionStatus.isSuccess();
        // If the deployment was a success, we also want to send a basic call which should always succeed.
        if (didDeploy) {
            AionAddress contractAddress = new AionAddress(deploymentResult.copyOfTransactionOutput().orElseThrow());
            Transaction callTransaction = AvmTransactionUtil.call(DEPLOYER, contractAddress, kernel.getNonce(DEPLOYER), BigInteger.ZERO, new byte[0], energyLimit, energyPrice);
            TransactionResult result = avm.run(kernel, new Transaction[] { callTransaction }, ExecutionType.replacedUME_MAINCHAIN, 0)[0].getResult();
            replacedert.replacedertTrue(result.transactionStatus.isSuccess());
        }
        // Now, shut down and return whether or not the deployment was a success.
        avm.shutdown();
        return didDeploy;
    }

    private int ceilingDivideByTwo(int value) {
        return (value + 1) / 2;
    }
}

19 Source : PocWalletTest.java
with MIT License
from aionnetwork

/**
 * Our current thinking is that we will use a JUnit launcher for the proof-of-concept demonstration.  This is that entry-point.
 * See issue-124 for more of the background.
 */
public clreplaced PocWalletTest {

    // For now, we will just reuse the from, to, and block for each call (in the future, this will change).
    private static AionAddress from = TestingState.PREMINED_ADDRESS;

    private static long energyLimit = 10_000_000_000L;

    private static long energyPrice = 1;

    private static IExternalState externalState;

    private static AvmImpl avm;

    private static IExternalCapabilities externalCapabilities;

    @BeforeClreplaced
    public static void setup() {
        TestingBlock block = new TestingBlock(new byte[32], 1, Helpers.randomAddress(), System.currentTimeMillis(), new byte[0]);
        externalState = new TestingState(block);
        externalCapabilities = new EmptyCapabilities() {

            @Override
            public byte[] blake2b(byte[] data) {
                // NOTE:  This test relies on calling blake2b but doesn't rely on the answer being correct so just return the input.
                return data;
            }
        };
        avm = CommonAvmFactory.buildAvmInstanceForConfiguration(externalCapabilities, new AvmConfiguration());
    }

    @AfterClreplaced
    public static void tearDown() {
        avm.shutdown();
    }

    private byte[] buildTestWalletJar() {
        return UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(Wallet.clreplaced, Multiowned.clreplaced, ByteArrayWrapper.clreplaced, Operation.clreplaced, ByteArrayHelpers.clreplaced, BytesKey.clreplaced, RequireFailedException.clreplaced, Daylimit.clreplaced, EventLogger.clreplaced);
    }

    /**
     * Tests that a deploy call will store the code for the Wallet JAR.
     * This means that it transformed it correctly and nothing was missing.
     */
    @Test
    public void testDeployWritesCode() {
        byte[] testWalletJar = buildTestWalletJar();
        byte[] testWalletArguments = new byte[0];
        Transaction createTransaction = AvmTransactionUtil.create(from, externalState.getNonce(from), BigInteger.ZERO, new CodeAndArguments(testWalletJar, testWalletArguments).encodeToBytes(), energyLimit, energyPrice);
        TransactionResult createResult = avm.run(externalState, new Transaction[] { createTransaction }, ExecutionType.replacedUME_MAINCHAIN, externalState.getBlockNumber() - 1)[0].getResult();
        replacedert.replacedertTrue(createResult.transactionStatus.isSuccess());
        replacedert.replacedertNotNull(externalState.getTransformedCode(new AionAddress(createResult.copyOfTransactionOutput().orElseThrow())));
    }

    /**
     * Tests that we can run init on the deployed code, albeit as a second transaction (since we haven't yet decided how to invoke init on deploy).
     */
    @Test
    public void testDeployAndCallInit() throws Exception {
        // Constructor args.
        AionAddress extra1 = Helpers.randomAddress();
        AionAddress extra2 = Helpers.randomAddress();
        int requiredVotes = 2;
        long dailyLimit = 5000;
        byte[] testWalletJar = buildTestWalletJar();
        byte[] testWalletArguments = new byte[0];
        Transaction createTransaction = AvmTransactionUtil.create(from, externalState.getNonce(from), BigInteger.ZERO, new CodeAndArguments(testWalletJar, testWalletArguments).encodeToBytes(), energyLimit, energyPrice);
        TransactionResult createResult = avm.run(externalState, new Transaction[] { createTransaction }, ExecutionType.replacedUME_MAINCHAIN, externalState.getBlockNumber() - 1)[0].getResult();
        replacedert.replacedertTrue(createResult.transactionStatus.isSuccess());
        // contract address is stored in return data
        AionAddress contractAddress = new AionAddress(createResult.copyOfTransactionOutput().orElseThrow());
        byte[] initArgs = CallEncoder.init(new Address(extra1.toByteArray()), new Address(extra2.toByteArray()), requiredVotes, dailyLimit);
        Transaction initTransaction = AvmTransactionUtil.call(from, contractAddress, externalState.getNonce(from), BigInteger.ZERO, initArgs, energyLimit, energyPrice);
        TransactionResult initResult = avm.run(externalState, new Transaction[] { initTransaction }, ExecutionType.replacedUME_MAINCHAIN, externalState.getBlockNumber() - 1)[0].getResult();
        replacedert.replacedertTrue(initResult.transactionStatus.isSuccess());
    }

    /**
     * Tests that inner clreplacedes work properly within the serialization system (since their constructors need to be marked accessible).
     */
    @Test
    public void testExecuteWithInnerClreplacedes() throws Exception {
        // Constructor args.
        AionAddress extra1 = Helpers.randomAddress();
        AionAddress extra2 = Helpers.randomAddress();
        int requiredVotes = 2;
        long dailyLimit = 5000;
        // Deploy.
        AionAddress contractAddress = new AionAddress(deployTestWallet());
        // Run the init.
        runInit(contractAddress, new Address(extra1.toByteArray()), new Address(extra2.toByteArray()), requiredVotes, dailyLimit);
        // Call "execute" with something above the daily limit so we will create the "Transaction" inner clreplaced instance.
        AionAddress to = Helpers.randomAddress();
        byte[] data = Helpers.randomBytes(AionAddress.LENGTH);
        byte[] execArgs = CallEncoder.execute(new Address(to.toByteArray()), dailyLimit + 1, data);
        Transaction executeTransaction = AvmTransactionUtil.call(from, contractAddress, externalState.getNonce(from), BigInteger.ZERO, execArgs, energyLimit, energyPrice);
        TransactionResult executeResult = avm.run(externalState, new Transaction[] { executeTransaction }, ExecutionType.replacedUME_MAINCHAIN, externalState.getBlockNumber() - 1)[0].getResult();
        replacedert.replacedertTrue(executeResult.transactionStatus.isSuccess());
        byte[] toConfirm = new ABIDecoder(executeResult.copyOfTransactionOutput().orElseThrow()).decodeOneByteArray();
        // Now, confirm as one of the other owners to observe we can instantiate the Transaction instance, from storage.
        externalState.adjustBalance(extra1, BigInteger.valueOf(1_000_000_000_000L));
        byte[] confirmArgs = CallEncoder.confirm(toConfirm);
        Transaction confirmTransaction = AvmTransactionUtil.call(extra1, contractAddress, externalState.getNonce(extra1), BigInteger.ZERO, confirmArgs, energyLimit, energyPrice);
        TransactionResult confirmResult = avm.run(externalState, new Transaction[] { confirmTransaction }, ExecutionType.replacedUME_MAINCHAIN, externalState.getBlockNumber() - 1)[0].getResult();
        // transfer to non-existing accounts
        replacedert.replacedertTrue(confirmResult.transactionStatus.isSuccess());
    }

    private void runInit(AionAddress contractAddress, Address extra1, Address extra2, int requiredVotes, long dailyLimit) throws Exception {
        byte[] initArgs = CallEncoder.init(extra1, extra2, requiredVotes, dailyLimit);
        Transaction initTransaction = AvmTransactionUtil.call(from, contractAddress, externalState.getNonce(from), BigInteger.ZERO, initArgs, energyLimit, energyPrice);
        TransactionResult initResult = avm.run(externalState, new Transaction[] { initTransaction }, ExecutionType.replacedUME_MAINCHAIN, externalState.getBlockNumber() - 1)[0].getResult();
        replacedert.replacedertTrue(initResult.transactionStatus.isSuccess());
    }

    private byte[] deployTestWallet() {
        byte[] testWalletJar = buildTestWalletJar();
        byte[] testWalletArguments = new byte[0];
        Transaction createTransaction = AvmTransactionUtil.create(from, externalState.getNonce(from), BigInteger.ZERO, new CodeAndArguments(testWalletJar, testWalletArguments).encodeToBytes(), energyLimit, energyPrice);
        TransactionResult createResult = avm.run(externalState, new Transaction[] { createTransaction }, ExecutionType.replacedUME_MAINCHAIN, externalState.getBlockNumber() - 1)[0].getResult();
        replacedert.replacedertTrue(createResult.transactionStatus.isSuccess());
        // contract address is stored in return data
        byte[] contractAddress = createResult.copyOfTransactionOutput().orElseThrow();
        return contractAddress;
    }
}

19 Source : TransformedCodeCacheTest.java
with MIT License
from aionnetwork

public clreplaced TransformedCodeCacheTest {

    private static AionAddress deployer = TestingState.PREMINED_ADDRESS;

    private static TestingBlock block;

    private static AvmImpl avm;

    @Before
    public void setupClreplaced() {
        block = new TestingBlock(new byte[32], 1, Helpers.randomAddress(), System.currentTimeMillis(), new byte[0]);
        avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
    }

    @After
    public void tearDown() {
        avm.shutdown();
    }

    @Test
    public void notWriteToCacheAfterSuccessfulTransactionTest() {
        TestingState kernel = new TestingState(block);
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        AionAddress dappAddress = deploy(deployer, kernel, txData);
        kernel.generateBlock();
        // remove the transformed code. This means the avm version has changed.
        // transformed code cache is empty.
        kernel.setTransformedCode(dappAddress, null);
        // this transaction will force a re-transformation operation to be done
        TransactionResult result = callDappNoArgument(kernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, 500_000);
        replacedert.replacedertEquals(10, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        // transformed code should be written to the database
        replacedert.replacedertNotNull(kernel.getTransformedCode(dappAddress));
        kernel.generateBlock();
        // validate in a successful transaction cache is not updated
        // This should force the re-transformation step to be done again since the cache is empty. Code is set to byte[0] to make re-transformation to fail.
        kernel.putCode(dappAddress, new byte[0]);
        kernel.setTransformedCode(dappAddress, null);
        // since it's not reading from the cache the result of the operation is failed
        result = callDappNoArgument(kernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, 500_000);
        replacedert.replacedertTrue(result.transactionStatus.isFailed());
        replacedert.replacedertEquals("Failed: re-transformation failure", result.transactionStatus.causeOfError);
    }

    @Test
    public void writeToCacheAfterFailedTransactionTest() {
        TestingState kernel = new TestingState(block);
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        AionAddress dappAddress = deploy(deployer, kernel, txData);
        kernel.generateBlock();
        // remove the transformed code. This means the avm version has changed.
        // transformed code cache is empty.
        kernel.setTransformedCode(dappAddress, null);
        // this transaction will run out of energy. It should write back the transformed code to cache
        TransactionResult result = callDappNoArgument(kernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, 25_000);
        replacedert.replacedertTrue(result.transactionStatus.isFailed());
        replacedert.replacedertEquals("Failed: out of energy", result.transactionStatus.causeOfError);
        replacedert.replacedertNull(kernel.getTransformedCode(dappAddress));
        // this should read from the cache. Code is set to byte[0] to make sure re-transformation step is not performed
        kernel.putCode(dappAddress, new byte[0]);
        kernel.generateBlock();
        // since it's reading from the cache the result of the operation is success
        result = callDappNoArgument(kernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, 2_000_000);
        replacedert.replacedertTrue(result.transactionStatus.isSuccess());
        replacedert.replacedertEquals(10, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        // since the transaction is successful, the transformed code should not be written back to the cache
        kernel.putCode(dappAddress, new byte[0]);
        kernel.setTransformedCode(dappAddress, null);
        // since it's not reading from the cache the result of the operation is failed
        result = callDappNoArgument(kernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, 500_000);
        replacedert.replacedertTrue(result.transactionStatus.isFailed());
        replacedert.replacedertEquals("Failed: re-transformation failure", result.transactionStatus.causeOfError);
    }

    @Test
    public void reorganizationTest() {
        TestingState kernel = new TestingState(block);
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        AionAddress dappAddress = deploy(deployer, kernel, txData);
        // remove the transformed code. This means the avm version has changed.
        // transformed code cache is empty.
        kernel.setTransformedCode(dappAddress, null);
        // this transaction will run out of energy. It should write back the transformed code to cache
        TransactionResult result = callDappNoArgument(kernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, 25_000);
        replacedert.replacedertTrue(result.transactionStatus.isFailed());
        replacedert.replacedertEquals("Failed: out of energy", result.transactionStatus.causeOfError);
        replacedert.replacedertNull(kernel.getTransformedCode(dappAddress));
        // If the chain the reorganizes and the transformed code for Avm1 is present, that should be used
        kernel.setTransformedCode(dappAddress, new byte[0]);
        // byte[0] as the transformed code will return null as a dApp, thus no code is executed
        result = callDappNoArgument(kernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, 2_000_000);
        replacedert.replacedertTrue(result.transactionStatus.isSuccess());
        replacedert.replacedertFalse(result.copyOfTransactionOutput().isPresent());
    }

    @Test
    public void internalTransactionTest() {
        TestingState kernel = new TestingState(block);
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        AionAddress dappAddress1 = deploy(deployer, kernel, txData);
        AionAddress dappAddress2 = deploy(deployer, kernel, txData);
        // remove the transformed code. This means the avm version has changed.
        // transformed code cache is empty.
        kernel.setTransformedCode(dappAddress1, null);
        kernel.setTransformedCode(dappAddress2, null);
        // this transaction will run out of energy. It should write back the transformed code to cache
        TransactionResult result = callDappNoArgument(kernel, deployer, dappAddress2, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, 25_000);
        replacedert.replacedertTrue(result.transactionStatus.isFailed());
        replacedert.replacedertNull(kernel.getTransformedCode(dappAddress2));
        // this ensures that only the cache is read and re-transformation is not done
        kernel.putCode(dappAddress2, new byte[0]);
        byte[] data = new ABIStreamingEncoder().encodeOneString("revert").toBytes();
        byte[] encodedData = new ABIStreamingEncoder().encodeOneString("makeCall").encodeOneAddress(new Address(dappAddress2.toByteArray())).encodeOneByteArray(data).toBytes();
        result = callDappArguments(kernel, deployer, dappAddress1, encodedData);
        replacedert.replacedertTrue(result.transactionStatus.isSuccess());
        replacedert.replacedertNull(kernel.getTransformedCode(dappAddress2));
    }

    @Test
    public void selfDestructTest() {
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        TestingState kernel = new TestingState(block);
        AionAddress dappAddress = deploy(deployer, kernel, txData);
        kernel.generateBlock();
        kernel.setTransformedCode(dappAddress, null);
        // transformed code is added to the cache
        callDappNoArgument(kernel, deployer, dappAddress, "selfDestruct", ExecutionType.replacedUME_MAINCHAIN, 2_000_000);
        replacedert.replacedertNull(kernel.getTransformedCode(dappAddress));
        replacedert.replacedertNull(kernel.getCode(dappAddress));
        kernel.generateBlock();
        TransactionResult result = callDappNoArgument(kernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, 2_000_000);
        replacedert.replacedertTrue(result.transactionStatus.isSuccess());
        replacedert.replacedertFalse(result.copyOfTransactionOutput().isPresent());
    }

    @Test
    public void notWriteToCacheAfterEthCallTest() {
        TestingState kernel = new TestingState(block);
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        AionAddress dappAddress = deploy(deployer, kernel, txData);
        kernel.generateBlock();
        // remove the transformed code. This means the avm version has changed.
        // transformed code cache is empty.
        kernel.setTransformedCode(dappAddress, null);
        // this transaction will force a re-transformation operation to be done
        TransactionResult result = callDappNoArgument(kernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.ETH_CALL, 500_000);
        replacedert.replacedertEquals(10, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        kernel.generateBlock();
        // validate in a successful transaction cache is not updated
        // This should force the re-transformation step to be done again since the cache is empty. Code is set to byte[0] to make re-transformation to fail.
        kernel.putCode(dappAddress, new byte[0]);
        kernel.setTransformedCode(dappAddress, null);
        // since it's not reading from the cache the result of the operation is failed
        result = callDappNoArgument(kernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, 500_000);
        replacedert.replacedertTrue(result.transactionStatus.isFailed());
        replacedert.replacedertEquals("Failed: re-transformation failure", result.transactionStatus.causeOfError);
    }

    @Test
    public void writeBackToCacheAfterEthCallTest() {
        TestingState kernel = new TestingState(block);
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        AionAddress dappAddress = deploy(deployer, kernel, txData);
        kernel.generateBlock();
        // remove the transformed code. This means the avm version has changed.
        // transformed code cache is empty.
        kernel.setTransformedCode(dappAddress, null);
        TransactionResult result = callDappNoArgument(kernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, 25_000);
        replacedert.replacedertTrue(result.transactionStatus.isFailed());
        // this transaction will read from the cache and write back
        result = callDappNoArgument(kernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.ETH_CALL, 500_000);
        replacedert.replacedertEquals(10, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        kernel.generateBlock();
        // Code is set to byte[0] to make re-transformation is not performed.
        kernel.putCode(dappAddress, new byte[0]);
        kernel.setTransformedCode(dappAddress, null);
        result = callDappNoArgument(kernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, 500_000);
        replacedert.replacedertTrue(result.transactionStatus.isSuccess());
        replacedert.replacedertEquals(20, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
    }

    @Test
    public void writeBackToCacheAfterMiningTest() {
        TestingState kernel = new TestingState(block);
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        AionAddress dappAddress = deploy(deployer, kernel, txData);
        kernel.generateBlock();
        // remove the transformed code. This means the avm version has changed.
        // transformed code cache is empty.
        kernel.setTransformedCode(dappAddress, null);
        // this transaction will run out of energy. It should write back the transformed code to cache
        TransactionResult result = callDappNoArgument(kernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, 25_000);
        replacedert.replacedertTrue(result.transactionStatus.isFailed());
        replacedert.replacedertNull(kernel.getTransformedCode(dappAddress));
        kernel.generateBlock();
        kernel.putCode(dappAddress, new byte[0]);
        // this transaction must read from the cache, thus should succeed
        result = callDappNoArgument(kernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.MINING, 500_000);
        replacedert.replacedertTrue(result.transactionStatus.isSuccess());
        replacedert.replacedertEquals(10, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        kernel.setTransformedCode(dappAddress, null);
        // this transaction must read from the cache, thus should succeed
        result = callDappNoArgument(kernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_SIDECHAIN, 500_000);
        replacedert.replacedertTrue(result.transactionStatus.isSuccess());
        replacedert.replacedertEquals(20, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
    }

    @Test
    public void deepSidechainTest() {
        TestingState kernel = new TestingState(block);
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        AionAddress dappAddress = deploy(deployer, kernel, txData);
        kernel.generateBlock();
        // remove the transformed code. This means the avm version has changed.
        // transformed code cache is empty.
        kernel.setTransformedCode(dappAddress, null);
        // this transaction will run out of energy. It should write back the transformed code to cache
        TransactionResult result = callDappNoArgument(kernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, 25_000);
        replacedert.replacedertTrue(result.transactionStatus.isFailed());
        replacedert.replacedertNull(kernel.getTransformedCode(dappAddress));
        kernel.generateBlock();
        kernel.putCode(dappAddress, new byte[0]);
        // since it's not reading from the cache the result of the operation is failed
        result = callDappNoArgument(kernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_DEEP_SIDECHAIN, 500_000);
        replacedert.replacedertTrue(result.transactionStatus.isFailed());
    }

    private static AionAddress deploy(AionAddress deployer, TestingState kernel, byte[] txData) {
        Transaction tx1 = AvmTransactionUtil.create(deployer, kernel.getNonce(deployer), BigInteger.ZERO, txData, 5_000_000, 1);
        TransactionResult result = avm.run(kernel, new Transaction[] { tx1 }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
        replacedertTrue(result.transactionStatus.isSuccess());
        return new AionAddress(result.copyOfTransactionOutput().orElseThrow());
    }

    private static TransactionResult callDappNoArgument(TestingState kernel, AionAddress sender, AionAddress dappAddress, String methodName, ExecutionType executionType, long energyLimit) {
        ABIStreamingEncoder encoder = new ABIStreamingEncoder().encodeOneString(methodName);
        byte[] data = encoder.toBytes();
        long commonBlockNumber = executionType == ExecutionType.replacedUME_DEEP_SIDECHAIN ? 0 : kernel.getBlockNumber() - 1;
        Transaction tx = AvmTransactionUtil.call(sender, dappAddress, kernel.getNonce(sender), BigInteger.ZERO, data, energyLimit, 1);
        return avm.run(kernel, new Transaction[] { tx }, executionType, commonBlockNumber)[0].getResult();
    }

    private static TransactionResult callDappArguments(TestingState kernel, AionAddress sender, AionAddress dappAddress, byte[] encodedData) {
        Transaction tx = AvmTransactionUtil.call(sender, dappAddress, kernel.getNonce(sender), BigInteger.ZERO, encodedData, (long) 2_000_000, 1);
        return avm.run(kernel, new Transaction[] { tx }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
    }
}

19 Source : HotObjectTest.java
with MIT License
from aionnetwork

public clreplaced HotObjectTest {

    // NOTE:  Output is ONLY produced if REPORT is set to true.
    private static final boolean REPORT = false;

    private static AionAddress deployer = TestingState.PREMINED_ADDRESS;

    private static TestingBlock block;

    private static AvmImpl avm;

    private static long energyLimit = 2_000_000L;

    private static long energyPrice = 1L;

    @Before
    public void setupClreplaced() {
        block = new TestingBlock(new byte[32], 1, Helpers.randomAddress(), System.currentTimeMillis(), new byte[0]);
        avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
    }

    @After
    public void tearDown() {
        avm.shutdown();
    }

    /**
     * Demonstrates executing two transactions to the same contract in one block
     * The code cache is invalidated before the execution of the tx3 since both transactions are in the same block
     */
    @Test
    public void executeMultipleTransactionSameBlock() {
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        TestingState kernel = new TestingState(block);
        AionAddress dappAddress = deploy(deployer, kernel, txData);
        TransactionResult result = callDapp(kernel, deployer, dappAddress, "doubleStaticValue");
        replacedert.replacedertEquals(10, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        kernel.adjustBalance(kernel.getMinerAddress(), BigInteger.TEN.pow(10));
        kernel.generateBlock();
        byte[] data = new ABIStreamingEncoder().encodeOneString("doubleStaticValue").toBytes();
        // read from the cache
        Transaction tx2 = AvmTransactionUtil.call(deployer, dappAddress, kernel.getNonce(deployer), BigInteger.ZERO, data, energyLimit, energyPrice);
        // read from DB
        Transaction tx3 = AvmTransactionUtil.call(kernel.getMinerAddress(), dappAddress, kernel.getNonce(kernel.getMinerAddress()), BigInteger.ZERO, data, energyLimit, energyPrice);
        FutureResult[] result2 = avm.run(kernel, new Transaction[] { tx2, tx3 }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(20, new ABIDecoder((result2[0].getResult()).copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        replacedert.replacedertEquals(40, new ABIDecoder((result2[1].getResult()).copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
    }

    /**
     * Demonstrates caching will not be used for an earlier block than the dapp's loaded block number
     */
    @Test
    public void executeTransactionEarlierBlock() {
        // setup kernel
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        TestingState kernel1 = new TestingState(block);
        AionAddress dapp1 = deploy(deployer, kernel1, txData);
        TestingState kernel2 = new TestingState(block);
        AionAddress dapp2 = deploy(deployer, kernel2, txData);
        // advance the block number
        kernel2.generateBlock();
        kernel2.generateBlock();
        replacedert.replacedertEquals(dapp1, dapp2);
        TransactionResult result = callDapp(kernel2, deployer, dapp2, "doubleStaticValue");
        replacedert.replacedertEquals(10, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        // execute same transaction on an earlier block
        result = callDapp(kernel1, deployer, dapp1, "doubleStaticValue");
        replacedert.replacedertEquals(10, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
    }

    /**
     * Demonstrates executing same transaction in the same contract in one block
     * The storage is reset between executions and field values are read from DB
     * The code cache is invalidated before the execution of the second transaction
     */
    @Test
    public void executeTransactionSameBlock() {
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        TestingState kernel = new TestingState(block);
        AionAddress dappAddress = deploy(deployer, kernel, txData);
        byte[] objectGraph = kernel.getObjectGraph(dappAddress);
        TransactionResult result = callDapp(kernel, deployer, dappAddress, "doubleStaticValue");
        replacedert.replacedertEquals(10, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        // reset the object graph
        kernel.putObjectGraph(dappAddress, objectGraph);
        result = callDapp(kernel, deployer, dappAddress, "doubleStaticValue");
        replacedert.replacedertEquals(10, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
    }

    /**
     * Demonstrates field value is read from cache not storage for a new block
     */
    @Test
    public void executeTransactionFromCache() {
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        TestingState kernel = new TestingState(block);
        AionAddress dappAddress = deploy(deployer, kernel, txData);
        byte[] objectGraph = kernel.getObjectGraph(dappAddress);
        TransactionResult result = callDapp(kernel, deployer, dappAddress, "doubleStaticValue");
        replacedert.replacedertEquals(10, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        // reset the object graph
        kernel.putObjectGraph(dappAddress, objectGraph);
        // reset the transformed code to ensure we're reading from the code cache
        kernel.setTransformedCode(dappAddress, new byte[0]);
        kernel.generateBlock();
        result = callDapp(kernel, deployer, dappAddress, "doubleStaticValue");
        replacedert.replacedertEquals(20, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
    }

    /**
     * Demonstrates the behaviour after revert.
     * Dapp code is stored and read from the cache. Dapp data is not written back
     */
    @Test
    public void executeTransactionRevert() {
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        TestingState kernel = new TestingState(block);
        AionAddress dappAddress = deploy(deployer, kernel, txData);
        kernel.generateBlock();
        // add dapp to cache
        TransactionResult result = callDapp(kernel, deployer, dappAddress, "doubleStaticValue");
        replacedert.replacedertEquals(10, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        kernel.generateBlock();
        result = callDapp(kernel, deployer, dappAddress, "revert");
        replacedert.replacedertTrue(result.transactionStatus.isReverted());
        kernel.generateBlock();
        // reset the transformed code to ensure we're reading from the code cache
        kernel.setTransformedCode(dappAddress, new byte[0]);
        result = callDapp(kernel, deployer, dappAddress, "getStr");
        replacedert.replacedertEquals("initial", new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneString());
    }

    /**
     * Demonstrates the behaviour after exception.
     * Dapp code is stored and read from the cache. Dapp data is not written back.
     */
    @Test
    public void executeTransactionException() {
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        TestingState kernel = new TestingState(block);
        AionAddress dappAddress = deploy(deployer, kernel, txData);
        kernel.generateBlock();
        // add dapp to cache
        TransactionResult result = callDapp(kernel, deployer, dappAddress, "doubleStaticValue");
        replacedert.replacedertEquals(10, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        kernel.generateBlock();
        result = callDapp(kernel, deployer, dappAddress, "exception");
        replacedert.replacedertEquals(AvmInternalError.FAILED_EXCEPTION.error, result.transactionStatus.causeOfError);
        kernel.generateBlock();
        // reset the transformed code to ensure we're reading from the code cache
        kernel.setTransformedCode(dappAddress, new byte[0]);
        result = callDapp(kernel, deployer, dappAddress, "getStr");
        replacedert.replacedertEquals("initial", new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneString());
    }

    /**
     * Demonstrates the behaviour after revert in a reentrant call.
     * State of Dapp is not updated in cache after the revert
     */
    @Test
    public void executeReentrantRevert() {
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] deployData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        TestingState kernel = new TestingState(block);
        AionAddress dappAddress = deploy(deployer, kernel, deployData);
        kernel.generateBlock();
        // add dapp to cache
        TransactionResult result = callDapp(kernel, deployer, dappAddress, "doubleStaticValue");
        replacedert.replacedertEquals(10, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        kernel.generateBlock();
        byte[] data = new ABIStreamingEncoder().encodeOneString("revert").toBytes();
        byte[] txData = new ABIStreamingEncoder().encodeOneString("makeCall").encodeOneAddress(new Address(dappAddress.toByteArray())).encodeOneByteArray(data).toBytes();
        Transaction tx = AvmTransactionUtil.call(deployer, dappAddress, kernel.getNonce(deployer), BigInteger.ZERO, txData, energyLimit, energyPrice);
        result = avm.run(kernel, new Transaction[] { tx }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
        replacedert.replacedertTrue(result.transactionStatus.isSuccess());
        kernel.generateBlock();
        result = callDapp(kernel, deployer, dappAddress, "getStr");
        replacedert.replacedertEquals("initial", new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneString());
    }

    /**
     * Demonstrates the behaviour in a reentrant call.
     * State of Dapp is updated in cache
     */
    @Test
    public void executeReentrantSuccess() {
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] deployData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        TestingState kernel = new TestingState(block);
        AionAddress dappAddress = deploy(deployer, kernel, deployData);
        kernel.generateBlock();
        // add dapp to cache
        TransactionResult result = callDapp(kernel, deployer, dappAddress, "doubleStaticValue");
        replacedert.replacedertEquals(10, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        kernel.generateBlock();
        byte[] data = new ABIStreamingEncoder().encodeOneString("doubleStaticValue").toBytes();
        byte[] txData = new ABIStreamingEncoder().encodeOneString("makeCall").encodeOneAddress(new Address(dappAddress.toByteArray())).encodeOneByteArray(data).toBytes();
        Transaction tx = AvmTransactionUtil.call(deployer, dappAddress, kernel.getNonce(deployer), BigInteger.ZERO, txData, energyLimit, energyPrice);
        result = avm.run(kernel, new Transaction[] { tx }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
        replacedert.replacedertTrue(result.transactionStatus.isSuccess());
        kernel.generateBlock();
        result = callDapp(kernel, deployer, dappAddress, "getValue");
        replacedert.replacedertEquals(20, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
    }

    /**
     * Demonstrates the difference in performance between reading from data cache and code cache
     */
    @Test
    public void performanceTest() {
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        TestingState kernel = new TestingState(block);
        AionAddress dappAddress = deploy(deployer, kernel, txData);
        // 307168 bytes
        byte[] data = new ABIStreamingEncoder().encodeOneString("writeToObjectArray").encodeOneInteger(150).encodeOneInteger(500).toBytes();
        Transaction tx = AvmTransactionUtil.call(deployer, dappAddress, kernel.getNonce(deployer), BigInteger.ZERO, data, energyLimit, energyPrice);
        TransactionResult result = avm.run(kernel, new Transaction[] { tx }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
        replacedert.replacedertTrue(result.transactionStatus.isSuccess());
        kernel.generateBlock();
        long cacheResult = measureMethodExecutionTime(kernel, dappAddress, "getValue", true, 5);
        long DBResult = measureMethodExecutionTime(kernel, dappAddress, "getValue", false, 5);
        if (REPORT) {
            System.out.println("Avg execution time (307168 serialized bytes) using code cache: " + DBResult + ", data cache: " + cacheResult + "(ns). code/data cache ratio: " + (double) DBResult / cacheResult);
        }
        // 8308 bytes
        data = new ABIStreamingEncoder().encodeOneString("writeToObjectArray").encodeOneInteger(15).encodeOneInteger(55).toBytes();
        tx = AvmTransactionUtil.call(deployer, dappAddress, kernel.getNonce(deployer), BigInteger.ZERO, data, energyLimit, energyPrice);
        result = avm.run(kernel, new Transaction[] { tx }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
        replacedert.replacedertTrue(result.transactionStatus.isSuccess());
        kernel.generateBlock();
        cacheResult = measureMethodExecutionTime(kernel, dappAddress, "getValue", true, 5);
        DBResult = measureMethodExecutionTime(kernel, dappAddress, "getValue", false, 5);
        if (REPORT) {
            System.out.println("Avg execution time (8308 serialized bytes) using code cache: " + DBResult + ", data cache: " + cacheResult + "(ns). code/data cache ratio: " + (double) DBResult / cacheResult);
        }
    }

    /**
     * Demonstrates the case one contract is making an internal call and updates another contract. All the data is read from the cache
     */
    @Test
    public void callOtherContractInCache() {
        int length = 2;
        AionAddress[] dappAddresses = new AionAddress[length];
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] deployData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        TestingState kernel = new TestingState(block);
        for (int i = 0; i < length; i++) {
            AionAddress deployer = Helpers.randomAddress();
            kernel.adjustBalance(deployer, BigInteger.TEN.pow(20));
            dappAddresses[i] = deploy(deployer, kernel, deployData);
            // add to cache
            TransactionResult result = callDapp(kernel, deployer, dappAddresses[i], "getValue");
            replacedert.replacedertEquals(5, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
            kernel.generateBlock();
        }
        byte[] objectGraph = kernel.getObjectGraph(dappAddresses[1]);
        // update the cache
        byte[] data = new ABIStreamingEncoder().encodeOneString("doubleStaticValue").toBytes();
        byte[] txData = new ABIStreamingEncoder().encodeOneString("makeCall").encodeOneAddress(new Address(dappAddresses[1].toByteArray())).encodeOneByteArray(data).toBytes();
        Transaction tx = AvmTransactionUtil.call(deployer, dappAddresses[0], kernel.getNonce(deployer), BigInteger.ZERO, txData, energyLimit, energyPrice);
        TransactionResult result = avm.run(kernel, new Transaction[] { tx }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
        replacedert.replacedertTrue(result.transactionStatus.isSuccess());
        kernel.generateBlock();
        // reset the object graph and transformed code to ensure data is read form cache
        for (int i = 0; i < length; i++) {
            kernel.putObjectGraph(dappAddresses[i], objectGraph);
            kernel.setTransformedCode(dappAddresses[i], new byte[0]);
        }
        // internal transaction result is not stored in the cache
        result = callDapp(kernel, deployer, dappAddresses[1], "getValue");
        replacedert.replacedertEquals(5, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        kernel.generateBlock();
        result = callDapp(kernel, deployer, dappAddresses[0], "getValue");
        replacedert.replacedertEquals(5, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
    }

    /**
     * Demonstrates the case where 2 contracts make internal calls and update each other. All the data is read from the cache
     */
    @Test
    public void InternalCallsBetween2Contracts() {
        int length = 2;
        AionAddress[] dappAddresses = new AionAddress[length];
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] deployData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        TestingState kernel = new TestingState(block);
        for (int i = 0; i < length; i++) {
            AionAddress deployer = Helpers.randomAddress();
            kernel.adjustBalance(deployer, BigInteger.TEN.pow(20));
            dappAddresses[i] = deploy(deployer, kernel, deployData);
            // add to cache
            TransactionResult result = callDapp(kernel, deployer, dappAddresses[i], "getValue");
            replacedert.replacedertEquals(5, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
            kernel.generateBlock();
        }
        byte[] objectGraph = kernel.getObjectGraph(dappAddresses[0]);
        // update the cache
        byte[] data = new ABIStreamingEncoder().encodeOneString("doubleStaticValue").toBytes();
        byte[] dataForCallFrom2To1 = new ABIStreamingEncoder().encodeOneString("makeCall").encodeOneAddress(new Address(dappAddresses[0].toByteArray())).encodeOneByteArray(data).toBytes();
        byte[] ForCallFrom1To2 = new ABIStreamingEncoder().encodeOneString("makeCall").encodeOneAddress(new Address(dappAddresses[1].toByteArray())).encodeOneByteArray(dataForCallFrom2To1).toBytes();
        Transaction tx = AvmTransactionUtil.call(deployer, dappAddresses[0], kernel.getNonce(deployer), BigInteger.ZERO, ForCallFrom1To2, energyLimit, energyPrice);
        TransactionResult result = avm.run(kernel, new Transaction[] { tx }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
        replacedert.replacedertTrue(result.transactionStatus.isSuccess());
        kernel.generateBlock();
        // reset the object graph and transformed code to ensure data is read form cache
        for (int i = 0; i < length; i++) {
            kernel.putObjectGraph(dappAddresses[i], objectGraph);
            kernel.setTransformedCode(dappAddresses[i], new byte[0]);
        }
        // internal transaction result is not stored in the cache
        result = callDapp(kernel, deployer, dappAddresses[1], "getCallCount");
        replacedert.replacedertEquals(0, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        kernel.generateBlock();
        result = callDapp(kernel, deployer, dappAddresses[0], "getCallCount");
        replacedert.replacedertEquals(1, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        kernel.generateBlock();
        result = callDapp(kernel, deployer, dappAddresses[0], "getValue");
        replacedert.replacedertEquals(10, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
    }

    /**
     * Executes and caches the result of array modifications and reads from the cache while executing transactions concurrently
     */
    @Test
    public void readConcurrentlyFromCache() {
        int length = 4;
        AionAddress[] dappAddresses = new AionAddress[length];
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        TestingState kernel = new TestingState(block);
        Transaction[] txs = new Transaction[length];
        byte[] readIntArrayData = new ABIStreamingEncoder().encodeOneString("readIntArray").toBytes();
        for (int i = 0; i < length; i++) {
            AionAddress deployer = Helpers.randomAddress();
            kernel.adjustBalance(deployer, BigInteger.TEN.pow(20));
            dappAddresses[i] = deploy(deployer, kernel, txData);
            // setup concurrent transactions
            txs[i] = AvmTransactionUtil.call(deployer, dappAddresses[i], kernel.getNonce(deployer), BigInteger.ZERO, readIntArrayData, energyLimit, energyPrice);
        }
        // add to cache
        for (int i = 0; i < length; i++) {
            byte[] data = new ABIStreamingEncoder().encodeOneString("updateIntArray").encodeOneInteger(i).toBytes();
            Transaction tx = AvmTransactionUtil.call(deployer, dappAddresses[i], kernel.getNonce(deployer), BigInteger.ZERO, data, energyLimit, energyPrice);
            TransactionResult result = avm.run(kernel, new Transaction[] { tx }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
            replacedert.replacedertTrue(result.transactionStatus.isSuccess());
            kernel.generateBlock();
        }
        // read from cache while executing concurrently
        FutureResult[] results = avm.run(kernel, txs, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1);
        for (int i = 0; i < length; i++) {
            TransactionResult r = results[i].getResult();
            replacedert.replacedertTrue(r.transactionStatus.isSuccess());
            int[] expectedResult = new int[length];
            expectedResult[i] = 10;
            replacedert.replacedertArrayEquals(expectedResult, new ABIDecoder(r.copyOfTransactionOutput().orElseThrow()).decodeOneIntegerArray());
        }
    }

    /**
     * Executes array modifications for different contracts concurrently, and caches the result. Then reads from the cache.
     */
    @Test
    public void addToCacheFromConcurrentExecutor() {
        int length = 4;
        AionAddress[] dappAddresses = new AionAddress[length];
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        TestingState kernel = new TestingState(block);
        Transaction[] txs = new Transaction[length];
        for (int i = 0; i < length; i++) {
            AionAddress deployer = Helpers.randomAddress();
            kernel.adjustBalance(deployer, BigInteger.TEN.pow(20));
            dappAddresses[i] = deploy(deployer, kernel, txData);
            // add to cache
            byte[] data = new ABIStreamingEncoder().encodeOneString("updateIntArray").encodeOneInteger(i).toBytes();
            txs[i] = AvmTransactionUtil.call(deployer, dappAddresses[i], kernel.getNonce(deployer), BigInteger.ZERO, data, energyLimit, energyPrice);
        }
        FutureResult[] results = avm.run(kernel, txs, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1);
        for (int i = 0; i < length; i++) {
            TransactionResult r = results[i].getResult();
            replacedert.replacedertTrue(r.transactionStatus.isSuccess());
        }
        kernel.generateBlock();
        for (int i = 0; i < length; i++) {
            byte[] data = new ABIStreamingEncoder().encodeOneString("readIntArray").toBytes();
            Transaction tx = AvmTransactionUtil.call(deployer, dappAddresses[i], kernel.getNonce(deployer), BigInteger.ZERO, data, energyLimit, energyPrice);
            TransactionResult result = avm.run(kernel, new Transaction[] { tx }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
            replacedert.replacedertTrue(result.transactionStatus.isSuccess());
            int[] expectedResult = new int[length];
            expectedResult[i] = 10;
            replacedert.replacedertArrayEquals(expectedResult, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneIntegerArray());
            kernel.generateBlock();
        }
    }

    @Test
    public void abortException() {
        int length = 4;
        AionAddress[] dappAddresses = new AionAddress[length + 1];
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] deployData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        TestingState kernel = new TestingState(block);
        byte[] dataForInternalCall = new ABIStreamingEncoder().encodeOneString("doubleStaticValue").toBytes();
        Transaction[] txs = new Transaction[length];
        for (int i = 0; i < length + 1; i++) {
            AionAddress deployer = Helpers.randomAddress();
            kernel.adjustBalance(deployer, BigInteger.TEN.pow(20));
            dappAddresses[i] = deploy(deployer, kernel, deployData);
            if (i > 0) {
                byte[] txData = new ABIStreamingEncoder().encodeOneString("makeCall").encodeOneAddress(new Address(dappAddresses[i].toByteArray())).encodeOneByteArray(dataForInternalCall).toBytes();
                txs[i - 1] = AvmTransactionUtil.call(deployer, dappAddresses[i - 1], kernel.getNonce(deployer), BigInteger.ZERO, txData, energyLimit, energyPrice);
            }
        }
        FutureResult[] results = avm.run(kernel, txs, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1);
        for (int i = 0; i < length; i++) {
            TransactionResult r = results[i].getResult();
            replacedert.replacedertTrue(r.transactionStatus.isSuccess());
        }
        kernel.generateBlock();
        byte[] data = new ABIStreamingEncoder().encodeOneString("getValue").toBytes();
        for (int i = 1; i < length; i++) {
            Transaction tx = AvmTransactionUtil.call(deployer, dappAddresses[i], kernel.getNonce(deployer), BigInteger.ZERO, data, energyLimit, energyPrice);
            TransactionResult result = avm.run(kernel, new Transaction[] { tx }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
            replacedert.replacedertTrue(result.transactionStatus.isSuccess());
            replacedert.replacedertEquals(10, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        }
    }

    @Test
    public void selfDestructThenSendTransaction() {
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        TestingState kernel = new TestingState(block);
        AionAddress dappAddress = deploy(deployer, kernel, txData);
        TransactionResult result = callDapp(kernel, deployer, dappAddress, "doubleStaticValue");
        replacedert.replacedertEquals(10, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        kernel.generateBlock();
        callDapp(kernel, deployer, dappAddress, "selfDestruct");
        kernel.generateBlock();
        result = callDapp(kernel, deployer, dappAddress, "doubleStaticValue");
        replacedert.replacedertTrue(result.transactionStatus.isSuccess());
        replacedert.replacedertFalse(result.copyOfTransactionOutput().isPresent());
    }

    /**
     * Demonstrates a cross call which fails. The dapp code is read from the cache but the data is cleared
     */
    @Test
    public void callOtherContractInCacheAndFail() {
        int length = 2;
        AionAddress[] dappAddresses = new AionAddress[length];
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] deployData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        TestingState kernel = new TestingState(block);
        for (int i = 0; i < length; i++) {
            AionAddress deployer = Helpers.randomAddress();
            kernel.adjustBalance(deployer, BigInteger.TEN.pow(20));
            dappAddresses[i] = deploy(deployer, kernel, deployData);
            // add to cache
            TransactionResult result = callDapp(kernel, deployer, dappAddresses[i], "getValue");
            replacedert.replacedertEquals(5, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
            kernel.generateBlock();
        }
        // save the current state of the object graph. this will be used later to ensure the value is not read from the cache
        byte[] objectGraph = kernel.getObjectGraph(dappAddresses[1]);
        TransactionResult result = callDapp(kernel, deployer, dappAddresses[1], "doubleStaticValue");
        replacedert.replacedertEquals(10, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        // update the cache
        byte[] data = new ABIStreamingEncoder().encodeOneString("revert").toBytes();
        byte[] txData = new ABIStreamingEncoder().encodeOneString("makeCall").encodeOneAddress(new Address(dappAddresses[1].toByteArray())).encodeOneByteArray(data).toBytes();
        Transaction tx = AvmTransactionUtil.call(deployer, dappAddresses[0], kernel.getNonce(deployer), BigInteger.ZERO, txData, energyLimit, energyPrice);
        result = avm.run(kernel, new Transaction[] { tx }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
        replacedert.replacedertTrue(result.transactionStatus.isSuccess());
        kernel.generateBlock();
        // reset the object graph and transformed code to ensure data is read form cache
        for (int i = 0; i < length; i++) {
            // object graph at this stage, had the initial value of 5
            kernel.putObjectGraph(dappAddresses[i], objectGraph);
            kernel.setTransformedCode(dappAddresses[i], new byte[0]);
        }
        // read the cache
        result = callDapp(kernel, deployer, dappAddresses[1], "getValue");
        replacedert.replacedertEquals(5, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        kernel.generateBlock();
        result = callDapp(kernel, deployer, dappAddresses[0], "getValue");
        replacedert.replacedertEquals(5, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
    }

    @Test
    public void testRevertExternalCall() {
        int length = 2;
        AionAddress[] dappAddresses = new AionAddress[length];
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] deployData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        TestingState kernel = new TestingState(block);
        for (int i = 0; i < length; i++) {
            AionAddress deployer = Helpers.randomAddress();
            kernel.adjustBalance(deployer, BigInteger.TEN.pow(20));
            dappAddresses[i] = deploy(deployer, kernel, deployData);
        }
        // update the cache
        byte[] data = new ABIStreamingEncoder().encodeOneString("doubleStaticValue").toBytes();
        byte[] txData = new ABIStreamingEncoder().encodeOneString("makeCallAndRevert").encodeOneAddress(new Address(dappAddresses[1].toByteArray())).encodeOneByteArray(data).toBytes();
        Transaction tx = AvmTransactionUtil.call(deployer, dappAddresses[0], kernel.getNonce(deployer), BigInteger.ZERO, txData, energyLimit, energyPrice);
        TransactionResult result = avm.run(kernel, new Transaction[] { tx }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
        replacedert.replacedertTrue(result.transactionStatus.isFailed());
        kernel.generateBlock();
        // reset the code to make sure it's read from the cache
        for (int i = 0; i < length; i++) {
            kernel.putCode(dappAddresses[i], new byte[0]);
        }
        // read from the storage
        result = callDapp(kernel, deployer, dappAddresses[1], "getValue");
        replacedert.replacedertEquals(5, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        kernel.generateBlock();
        result = callDapp(kernel, deployer, dappAddresses[0], "getValue");
        replacedert.replacedertEquals(5, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
    }

    @Test
    public void testFailedExternalCall() {
        int length = 2;
        AionAddress[] dappAddresses = new AionAddress[length];
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] deployData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        TestingState kernel = new TestingState(block);
        for (int i = 0; i < length; i++) {
            AionAddress deployer = Helpers.randomAddress();
            kernel.adjustBalance(deployer, BigInteger.TEN.pow(20));
            dappAddresses[i] = deploy(deployer, kernel, deployData);
        }
        // update the cache
        byte[] data = new ABIStreamingEncoder().encodeOneString("doubleStaticValue").toBytes();
        byte[] txData = new ABIStreamingEncoder().encodeOneString("makeCallAndFail").encodeOneAddress(new Address(dappAddresses[1].toByteArray())).encodeOneByteArray(data).toBytes();
        Transaction tx = AvmTransactionUtil.call(deployer, dappAddresses[0], kernel.getNonce(deployer), BigInteger.ZERO, txData, 1933022, energyPrice);
        TransactionResult result = avm.run(kernel, new Transaction[] { tx }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
        replacedert.replacedertTrue(result.transactionStatus.isFailed());
        kernel.generateBlock();
        // reset the code to make sure it's read from the cache
        for (int i = 0; i < length; i++) {
            kernel.putCode(dappAddresses[i], new byte[0]);
        }
        // read from the storage
        result = callDapp(kernel, deployer, dappAddresses[1], "getValue");
        replacedert.replacedertEquals(5, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        kernel.generateBlock();
        result = callDapp(kernel, deployer, dappAddresses[0], "getValue");
        replacedert.replacedertEquals(5, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
    }

    private static long measureMethodExecutionTime(TestingState kernel, AionAddress dappAddress, String methodName, boolean generateBlock, int rounds) {
        long totalDuration = 0l;
        for (int i = 0; i < rounds; ++i) {
            long start = System.nanoTime();
            TransactionResult result = callDapp(kernel, deployer, dappAddress, methodName);
            totalDuration += (System.nanoTime() - start);
            replacedert.replacedertTrue(result.transactionStatus.isSuccess());
            if (generateBlock && i != rounds - 1) {
                kernel.generateBlock();
            }
        }
        return totalDuration / rounds;
    }

    private static AionAddress deploy(AionAddress deployer, TestingState kernel, byte[] txData) {
        Transaction tx1 = AvmTransactionUtil.create(deployer, kernel.getNonce(deployer), BigInteger.ZERO, txData, 5_000_000, energyPrice);
        TransactionResult result = avm.run(kernel, new Transaction[] { tx1 }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
        replacedertTrue(result.transactionStatus.isSuccess());
        return new AionAddress(result.copyOfTransactionOutput().orElseThrow());
    }

    private static TransactionResult callDapp(TestingState kernel, AionAddress sender, AionAddress dappAddress, String methodName, Object... args) {
        ABIStreamingEncoder encoder = new ABIStreamingEncoder().encodeOneString(methodName);
        for (Object arg : args) {
            encoder.encodeOneByteArray((byte[]) arg);
        }
        byte[] data = encoder.toBytes();
        Transaction tx = AvmTransactionUtil.call(sender, dappAddress, kernel.getNonce(sender), BigInteger.ZERO, data, energyLimit, energyPrice);
        return avm.run(kernel, new Transaction[] { tx }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
    }
}

19 Source : ExecutionTypeCacheTest.java
with MIT License
from aionnetwork

public clreplaced ExecutionTypeCacheTest {

    private static AionAddress deployer = TestingState.PREMINED_ADDRESS;

    private static TestingBlock block;

    private static AvmImpl avm;

    @Before
    public void setupClreplaced() {
        block = new TestingBlock(new byte[32], 1, Helpers.randomAddress(), System.currentTimeMillis(), new byte[0]);
        avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
    }

    @After
    public void tearDown() {
        avm.shutdown();
    }

    /**
     * Tests the case where the code cache block is after the common ancestor. Thus, caching will not be used.
     */
    @Test
    public void sidechainInvalidCodeCache() {
        TestingState sidechainKernel = new TestingState(block);
        TestingState mainchainKernel = new TestingState(block);
        // deploy to both
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        AionAddress dappAddress = deploy(deployer, mainchainKernel, txData);
        deploy(deployer, sidechainKernel, txData);
        mainchainKernel.generateBlock();
        sidechainKernel.generateBlock();
        long commonParent = mainchainKernel.getBlockNumber();
        mainchainKernel.generateBlock();
        // add to cache on mainchain
        TransactionResult result = callDapp(mainchainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, mainchainKernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(10, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        // generate sidechain block with parent on mainchain
        sidechainKernel.generateBlock();
        // reset the transformed code on the kernel
        sidechainKernel.setTransformedCode(dappAddress, new byte[0]);
        // since it's not reading from the cache the result of the revert operation is success
        result = callDapp(sidechainKernel, deployer, dappAddress, "revert", ExecutionType.replacedUME_SIDECHAIN, commonParent);
        replacedert.replacedertTrue(result.transactionStatus.isSuccess());
        // validate mainchain cache is valid
        mainchainKernel.generateBlock();
        // reset to ensure cache is used
        mainchainKernel.setTransformedCode(dappAddress, new byte[0]);
        mainchainKernel.putObjectGraph(dappAddress, new byte[0]);
        // read from the cache to make sure it's not corrupted
        result = callDapp(mainchainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, mainchainKernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(20, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
    }

    /**
     * Tests the case where both code and data cache have been put before the common ancestor.
     * They can both be used but only the code is written back.
     */
    @Test
    public void sidechainValidCodeCacheValidDataCache() {
        TestingState sidechainKernel = new TestingState(block);
        TestingState mainchainKernel = new TestingState(block);
        // deploy to both
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        AionAddress dappAddress = deploy(deployer, mainchainKernel, txData);
        deploy(deployer, sidechainKernel, txData);
        mainchainKernel.generateBlock();
        sidechainKernel.generateBlock();
        // add to cache on mainchain
        TransactionResult result = callDapp(mainchainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, mainchainKernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(10, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        sidechainKernel.generateBlock();
        mainchainKernel.generateBlock();
        long commonParent = mainchainKernel.getBlockNumber();
        mainchainKernel.generateBlock();
        sidechainKernel.generateBlock();
        // reset the transformed code on the kernel
        sidechainKernel.setTransformedCode(dappAddress, new byte[0]);
        // it should only read the code form cache
        result = callDapp(sidechainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_SIDECHAIN, commonParent);
        replacedert.replacedertEquals(20, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        mainchainKernel.generateBlock();
        // update the data cache on mainchain
        result = callDapp(mainchainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, mainchainKernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(20, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
    }

    /**
     * Tests the case where the code cache block number is below and the data cache block number is after the common ancestor
     * Code cache will be used but data cache will not be.
     * At the end of the transaction dapp code will be written back to the cache
     */
    @Test
    public void sidechainValidCodeCacheInvalidDataCache() {
        TestingState sidechainKernel = new TestingState(block);
        TestingState mainchainKernel = new TestingState(block);
        // deploy to both
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        AionAddress dappAddress = deploy(deployer, mainchainKernel, txData);
        deploy(deployer, sidechainKernel, txData);
        mainchainKernel.generateBlock();
        sidechainKernel.generateBlock();
        // add to cache on mainchain
        TransactionResult result = callDapp(mainchainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, mainchainKernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(10, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        sidechainKernel.generateBlock();
        mainchainKernel.generateBlock();
        long commonParent = mainchainKernel.getBlockNumber();
        mainchainKernel.generateBlock();
        // update the data cache on mainchain
        result = callDapp(mainchainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, mainchainKernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(20, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        sidechainKernel.generateBlock();
        // reset the transformed code on the kernel
        sidechainKernel.setTransformedCode(dappAddress, new byte[0]);
        // it should only read the code form cache
        result = callDapp(sidechainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_SIDECHAIN, commonParent);
        replacedert.replacedertEquals(10, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        // reset the transformed code on the kernel
        mainchainKernel.setTransformedCode(dappAddress, new byte[0]);
        mainchainKernel.generateBlock();
        // update the data cache on mainchain
        result = callDapp(mainchainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, mainchainKernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(40, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
    }

    /**
     * Tests the case where dapp is not included in the cache.
     * After the transaction cache will not be updated.
     */
    @Test
    public void sidechainNotInCache() {
        TestingState sidechainKernel = new TestingState(block);
        TestingState mainchainKernel = new TestingState(block);
        // deploy to both
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        AionAddress dappAddress = deploy(deployer, mainchainKernel, txData);
        deploy(deployer, sidechainKernel, txData);
        sidechainKernel.generateBlock();
        mainchainKernel.generateBlock();
        long commonParent = mainchainKernel.getBlockNumber();
        mainchainKernel.generateBlock();
        sidechainKernel.generateBlock();
        // it should only read the code form cache
        TransactionResult result = callDapp(sidechainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_SIDECHAIN, commonParent);
        replacedert.replacedertEquals(10, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        mainchainKernel.generateBlock();
        // update the data cache on mainchain
        result = callDapp(mainchainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, mainchainKernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(10, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
    }

    /**
     * It sequentially adds mainchain and deep sidechain blocks.
     * Sidechain blocks do not interact with cache while mainchain blocks are stored in both data and code cache
     */
    @Test
    public void multipleDeepSidechainBlockTest() {
        TestingState sidechainKernel = new TestingState(block);
        TestingState mainchainKernel = new TestingState(block);
        // deploy to both
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        AionAddress dappAddress = deploy(deployer, mainchainKernel, txData);
        deploy(deployer, sidechainKernel, txData);
        // add to cache
        TransactionResult result = callDapp(mainchainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, mainchainKernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(10, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        mainchainKernel.generateBlock();
        sidechainKernel.generateBlock();
        // update cache
        result = callDapp(mainchainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, mainchainKernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(20, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        mainchainKernel.generateBlock();
        sidechainKernel.generateBlock();
        result = callDapp(sidechainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_DEEP_SIDECHAIN, 0);
        replacedert.replacedertEquals(10, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        result = callDapp(mainchainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, mainchainKernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(40, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        mainchainKernel.generateBlock();
        sidechainKernel.generateBlock();
        result = callDapp(sidechainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_DEEP_SIDECHAIN, 0);
        replacedert.replacedertEquals(20, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        result = callDapp(mainchainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, mainchainKernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(80, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
    }

    /**
     * Tests the case where mining is done after a mainchain import
     * ensures code is read from cache and written back
     */
    @Test
    public void miningMainchainMixtureTest() {
        TestingState miningKernel = new TestingState(block);
        // deploy to both
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        AionAddress dappAddress = deploy(deployer, miningKernel, txData);
        miningKernel.generateBlock();
        TransactionResult result = callDapp(miningKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.MINING, miningKernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(10, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        miningKernel.generateBlock();
        // add to cache
        result = callDapp(miningKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, miningKernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(20, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        miningKernel.generateBlock();
        // make sure it's read from the cache
        miningKernel.setTransformedCode(dappAddress, new byte[0]);
        result = callDapp(miningKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.MINING, miningKernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(40, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        miningKernel.generateBlock();
        // make sure it was written back to cache
        miningKernel.setTransformedCode(dappAddress, new byte[0]);
        result = callDapp(miningKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, miningKernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(80, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
    }

    /**
     * Tests the case where mining is done after a mainchain import
     * ensures data is not written back to the cache
     */
    @Test
    public void miningMainchainMixtureNoDataTest() {
        TestingState miningKernel = new TestingState(block);
        // deploy to both
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        AionAddress dappAddress = deploy(deployer, miningKernel, txData);
        miningKernel.generateBlock();
        byte[] graph = miningKernel.getObjectGraph(dappAddress);
        TransactionResult result = callDapp(miningKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.MINING, miningKernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(10, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        miningKernel.generateBlock();
        // add to cache
        result = callDapp(miningKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, miningKernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(20, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        miningKernel.generateBlock();
        // make sure it's read from the cache
        miningKernel.setTransformedCode(dappAddress, new byte[0]);
        // reset the data in db, to ensure cache data is not read
        miningKernel.putObjectGraph(dappAddress, graph);
        result = callDapp(miningKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.MINING, miningKernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(10, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        miningKernel.generateBlock();
        // make sure it was wriiten back to cache
        miningKernel.setTransformedCode(dappAddress, new byte[0]);
        // rest the data to ensure data is not read from the cache
        miningKernel.putObjectGraph(dappAddress, graph);
        result = callDapp(miningKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, miningKernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(10, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        miningKernel.generateBlock();
        // make sure it was wriiten back to cache
        miningKernel.setTransformedCode(dappAddress, new byte[0]);
        // rest the data to ensure data is not read from the cache
        miningKernel.putObjectGraph(dappAddress, graph);
        result = callDapp(miningKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, miningKernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(20, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
    }

    /**
     * It simulates running one transaction in multiple blocks during mining.
     * Mining blocks do not interact with cache.
     */
    @Test
    public void sameMiningBlockTest() {
        TestingState miningKernel = new TestingState(block);
        // deploy to both
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        AionAddress dappAddress = deploy(deployer, miningKernel, txData);
        miningKernel.generateBlock();
        AionAddress sender = Helpers.randomAddress();
        miningKernel.adjustBalance(sender, BigInteger.TEN.pow(20));
        miningKernel.generateBlock();
        byte[] graph = miningKernel.getObjectGraph(dappAddress);
        TransactionResult result = callDapp(miningKernel, sender, dappAddress, "doubleStaticValue", ExecutionType.MINING, miningKernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(10, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        miningKernel.generateBlock();
        miningKernel.deleteAccount(sender);
        miningKernel.adjustBalance(sender, BigInteger.TEN.pow(20));
        miningKernel.putObjectGraph(dappAddress, graph);
        result = callDapp(miningKernel, sender, dappAddress, "doubleStaticValue", ExecutionType.MINING, miningKernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(10, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
    }

    /**
     * Builds mainchain and sidechain simultaneously. Then marks the sidechain as the new mainchain
     */
    @Test
    public void switchMainchainTest() {
        TestingState sidechainKernel = new TestingState(block);
        TestingState mainchainKernel = new TestingState(block);
        // deploy to both
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        AionAddress dappAddress = deploy(deployer, mainchainKernel, txData);
        deploy(deployer, sidechainKernel, txData);
        // add to cache for mainchain kernel
        TransactionResult result = callDapp(mainchainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, mainchainKernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(10, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        // add to cache for sidechain kernel
        result = callDapp(sidechainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, sidechainKernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(10, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        long commonParent = mainchainKernel.getBlockNumber();
        // fork
        mainchainKernel.generateBlock();
        sidechainKernel.generateBlock();
        // update cache for mainchain kernel
        result = callDapp(mainchainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, mainchainKernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(20, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        mainchainKernel.generateBlock();
        sidechainKernel.generateBlock();
        // update cache for mainchain kernel
        result = callDapp(mainchainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, mainchainKernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(40, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        // update db for sidechain kernel
        result = callDapp(sidechainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_DEEP_SIDECHAIN, 0);
        replacedert.replacedertEquals(20, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        sidechainKernel.generateBlock();
        // ensure cache is used
        sidechainKernel.setTransformedCode(dappAddress, new byte[0]);
        // mark the sidechain as the new mainchain
        result = callDapp(sidechainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.SWITCHING_MAINCHAIN, commonParent);
        replacedert.replacedertEquals(40, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
    }

    /**
     * Builds mainchain and sidechain simultaneously. Contract is selfdestructed on the sidechain but still remains in the cache
     */
    @Test
    public void switchMainchainSelfDestructTest() {
        TestingState sidechainKernel = new TestingState(block);
        TestingState mainchainKernel = new TestingState(block);
        // deploy to both
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        AionAddress dappAddress = deploy(deployer, mainchainKernel, txData);
        deploy(deployer, sidechainKernel, txData);
        // add to cache for mainchain kernel
        TransactionResult result = callDapp(mainchainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, mainchainKernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(10, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        // add to cache for sidechain kernel
        result = callDapp(sidechainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, sidechainKernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(10, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        long commonParent = mainchainKernel.getBlockNumber();
        // fork
        mainchainKernel.generateBlock();
        sidechainKernel.generateBlock();
        // update cache for mainchain kernel
        result = callDapp(mainchainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, mainchainKernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(20, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        mainchainKernel.generateBlock();
        sidechainKernel.generateBlock();
        // update cache for mainchain kernel
        result = callDapp(mainchainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, mainchainKernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(40, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        // update db for sidechain kernel
        result = callDapp(sidechainKernel, deployer, dappAddress, "selfDestruct", ExecutionType.replacedUME_DEEP_SIDECHAIN, 0);
        replacedert.replacedertTrue(result.transactionStatus.isSuccess());
        sidechainKernel.generateBlock();
        // mark the sidechain as the new mainchain
        result = callDapp(sidechainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.SWITCHING_MAINCHAIN, commonParent);
        replacedert.replacedertTrue(result.transactionStatus.isSuccess());
        replacedert.replacedertFalse(result.copyOfTransactionOutput().isPresent());
    }

    /**
     * Tests ethcall without valid cache. Dapp code will not be written back to the cache
     */
    @Test
    public void ethCallWithoutCacheValidateCodeNotWrittenBack() {
        TestingState mainchainKernel = new TestingState(block);
        // deploy to both
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        AionAddress dappAddress = deploy(deployer, mainchainKernel, txData);
        mainchainKernel.generateBlock();
        mainchainKernel.generateBlock();
        TransactionResult result = callDapp(mainchainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.ETH_CALL, mainchainKernel.getBlockNumber() - 1);
        replacedert.replacedertTrue(result.transactionStatus.isSuccess());
        mainchainKernel.generateBlock();
        // reset the transformed code and object graph on the kernel
        mainchainKernel.setTransformedCode(dappAddress, new byte[0]);
        result = callDapp(mainchainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, mainchainKernel.getBlockNumber() - 1);
        replacedert.replacedertFalse(result.copyOfTransactionOutput().isPresent());
    }

    /**
     * Tests ethcall without valid cache. Dapp data will not be written back to the cache
     */
    @Test
    public void ethCallWithoutCacheValidateDataNotWrittenBack() {
        TestingState mainchainKernel = new TestingState(block);
        // deploy to both
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        AionAddress dappAddress = deploy(deployer, mainchainKernel, txData);
        mainchainKernel.generateBlock();
        byte[] graph = mainchainKernel.getObjectGraph(dappAddress);
        mainchainKernel.generateBlock();
        TransactionResult result = callDapp(mainchainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.ETH_CALL, mainchainKernel.getBlockNumber() - 1);
        replacedert.replacedertTrue(result.transactionStatus.isSuccess());
        mainchainKernel.generateBlock();
        // reset the transformed code and object graph on the kernel
        mainchainKernel.putObjectGraph(dappAddress, graph);
        result = callDapp(mainchainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, mainchainKernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(10, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
    }

    /**
     * Tests the case where the code cache block is after the common ancestor. Thus, caching will not be used.
     */
    @Test
    public void ethCallInvalidCodeCache() {
        TestingState mainchainKernel = new TestingState(block);
        // deploy to both
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        AionAddress dappAddress = deploy(deployer, mainchainKernel, txData);
        mainchainKernel.generateBlock();
        long commonParent = mainchainKernel.getBlockNumber();
        mainchainKernel.generateBlock();
        mainchainKernel.generateBlock();
        // add to cache on mainchain
        TransactionResult result = callDapp(mainchainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, mainchainKernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(10, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        // generate sidechain block with parent on mainchain
        mainchainKernel.generateBlock();
        // reset the transformed code on the kernel
        mainchainKernel.setTransformedCode(dappAddress, new byte[0]);
        // since it's not reading from the cache the result of the revert operation is success
        result = callDapp(mainchainKernel, deployer, dappAddress, "revert", ExecutionType.ETH_CALL, commonParent);
        replacedert.replacedertTrue(result.transactionStatus.isSuccess());
        // validate mainchain cache is valid
        mainchainKernel.generateBlock();
        // reset to ensure cache is used
        mainchainKernel.setTransformedCode(dappAddress, new byte[0]);
        mainchainKernel.putObjectGraph(dappAddress, new byte[0]);
        // read from the cache to make sure it's not corrupted
        result = callDapp(mainchainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, mainchainKernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(20, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
    }

    /**
     * Tests the case where both code and data cache have been put before the common ancestor.
     * They can both be used but only the code is written back.
     */
    @Test
    public void ethCallValidCodeCacheValidDataCache() {
        TestingState mainchainKernel = new TestingState(block);
        // deploy to both
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        AionAddress dappAddress = deploy(deployer, mainchainKernel, txData);
        mainchainKernel.generateBlock();
        // add to cache on mainchain
        TransactionResult result = callDapp(mainchainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, mainchainKernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(10, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        mainchainKernel.generateBlock();
        long commonParent = mainchainKernel.getBlockNumber();
        mainchainKernel.generateBlock();
        mainchainKernel.generateBlock();
        // reset the transformed code on the kernel
        mainchainKernel.setTransformedCode(dappAddress, new byte[0]);
        byte[] graph = mainchainKernel.getObjectGraph(dappAddress);
        mainchainKernel.putObjectGraph(dappAddress, new byte[0]);
        // it should only read the code form cache
        result = callDapp(mainchainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.ETH_CALL, commonParent);
        replacedert.replacedertEquals(20, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        mainchainKernel.generateBlock();
        mainchainKernel.setTransformedCode(dappAddress, new byte[0]);
        // rest the graph to before the cll
        mainchainKernel.putObjectGraph(dappAddress, graph);
        // update the data cache on mainchain
        result = callDapp(mainchainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, mainchainKernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(20, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
    }

    /**
     * Tests the case where the code cache block number is below and the data cache block number is after the common ancestor
     * Code cache will be used but data cache will not be.
     * At the end of the transaction dapp code will be written back to the cache
     */
    @Test
    public void ethCallValidCodeCacheInvalidDataCache() {
        TestingState mainchainKernel = new TestingState(block);
        // deploy to both
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(HotObjectContract.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        AionAddress dappAddress = deploy(deployer, mainchainKernel, txData);
        mainchainKernel.generateBlock();
        // add to cache on mainchain
        TransactionResult result = callDapp(mainchainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, mainchainKernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(10, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        mainchainKernel.generateBlock();
        long commonParent = mainchainKernel.getBlockNumber();
        mainchainKernel.generateBlock();
        byte[] graphEthCallBlock = mainchainKernel.getObjectGraph(dappAddress);
        // update the data cache on mainchain
        result = callDapp(mainchainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, mainchainKernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(20, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        mainchainKernel.generateBlock();
        result = callDapp(mainchainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, mainchainKernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(40, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        mainchainKernel.generateBlock();
        byte[] graphMainChainLatest = mainchainKernel.getObjectGraph(dappAddress);
        // reset the transformed code on the kernel
        mainchainKernel.setTransformedCode(dappAddress, new byte[0]);
        // rest database to the common parent state. cache reflects value = 40 now and the db reflects value = 10
        mainchainKernel.putObjectGraph(dappAddress, graphEthCallBlock);
        // it should only read the code form cache
        result = callDapp(mainchainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.ETH_CALL, commonParent);
        replacedert.replacedertEquals(20, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        // reset the transformed code on the kernel
        mainchainKernel.setTransformedCode(dappAddress, new byte[0]);
        // make sure the db with value = 40 is read and cache is not updated after eth_call
        mainchainKernel.putObjectGraph(dappAddress, graphMainChainLatest);
        mainchainKernel.generateBlock();
        // update the data cache on mainchain
        result = callDapp(mainchainKernel, deployer, dappAddress, "doubleStaticValue", ExecutionType.replacedUME_MAINCHAIN, mainchainKernel.getBlockNumber() - 1);
        replacedert.replacedertEquals(80, new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
    }

    /**
     * Tests executing sidechain transactions concurrently. all dapps are put back in the cache
     */
    @Test
    public void concurrentSidechainExecution() {
        byte[] code = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(TestContract.clreplaced);
        TestingState mainchainKernel = new TestingState(block);
        TestingState sidechainKernel = new TestingState(block);
        int length = 4;
        AionAddress[] user = new AionAddress[length];
        Transaction[] ctx = new Transaction[length];
        for (int i = 0; i < length; i++) {
            user[i] = Helpers.randomAddress();
            mainchainKernel.adjustBalance(user[i], BigInteger.TEN.pow(20));
            sidechainKernel.adjustBalance(user[i], BigInteger.TEN.pow(20));
            ctx[i] = AvmTransactionUtil.create(user[i], BigInteger.ZERO, BigInteger.ZERO, new CodeAndArguments(code, null).encodeToBytes(), 5_000_000L, 1);
        }
        FutureResult[] results = avm.run(mainchainKernel, ctx, ExecutionType.replacedUME_MAINCHAIN, mainchainKernel.getBlockNumber() - 1);
        AionAddress[] contractAddresses = new AionAddress[results.length];
        for (int i = 0; i < results.length; i++) {
            contractAddresses[i] = new AionAddress(results[i].getResult().copyOfTransactionOutput().orElseThrow());
        }
        results = avm.run(sidechainKernel, ctx, ExecutionType.replacedUME_MAINCHAIN, sidechainKernel.getBlockNumber() - 1);
        for (int i = 0; i < results.length; i++) {
            contractAddresses[i] = new AionAddress(results[i].getResult().copyOfTransactionOutput().orElseThrow());
        }
        long commonParent = mainchainKernel.getBlockNumber();
        mainchainKernel.generateBlock();
        Transaction[] tx = new Transaction[results.length - 1];
        // u1->A->B, u2->B->C, u3->C->D
        for (int i = 0; i < results.length - 1; i++) {
            byte[] callData = new ABIStreamingEncoder().encodeOneString("doCallOther").encodeOneAddress(new Address(contractAddresses[i + 1].toByteArray())).encodeOneByteArray(new ABIStreamingEncoder().encodeOneString("addValue").toBytes()).toBytes();
            tx[i] = AvmTransactionUtil.call(user[i], contractAddresses[i], mainchainKernel.getNonce(user[i]), BigInteger.ZERO, callData, 5_000_000, 1);
        }
        results = avm.run(mainchainKernel, tx, ExecutionType.replacedUME_MAINCHAIN, mainchainKernel.getBlockNumber() - 1);
        for (FutureResult f : results) {
            f.getResult();
        }
        sidechainKernel.generateBlock();
        // validate the state of contracts
        for (int i = 0; i < length - 1; i++) {
            byte[] getCallCount = new ABIStreamingEncoder().encodeOneString("getCallCount").toBytes();
            tx[i] = AvmTransactionUtil.call(user[i], contractAddresses[i], sidechainKernel.getNonce(user[i]), BigInteger.ZERO, getCallCount, 5_000_000, 1);
        }
        results = avm.run(sidechainKernel, tx, ExecutionType.replacedUME_SIDECHAIN, commonParent);
        for (FutureResult f : results) {
            replacedert.replacedertEquals(0, new ABIDecoder(f.getResult().copyOfTransactionOutput().orElseThrow()).decodeOneInteger());
        }
    }

    private static AionAddress deploy(AionAddress deployer, TestingState kernel, byte[] txData) {
        Transaction tx1 = AvmTransactionUtil.create(deployer, kernel.getNonce(deployer), BigInteger.ZERO, txData, 5_000_000, 1);
        TransactionResult result = avm.run(kernel, new Transaction[] { tx1 }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
        replacedertTrue(result.transactionStatus.isSuccess());
        return new AionAddress(result.copyOfTransactionOutput().orElseThrow());
    }

    private static TransactionResult callDapp(TestingState kernel, AionAddress sender, AionAddress dappAddress, String methodName, ExecutionType executionType, long commonMainchainBlockNumber, Object... args) {
        ABIStreamingEncoder encoder = new ABIStreamingEncoder().encodeOneString(methodName);
        for (Object arg : args) {
            encoder.encodeOneByteArray((byte[]) arg);
        }
        byte[] data = encoder.toBytes();
        Transaction tx = AvmTransactionUtil.call(sender, dappAddress, kernel.getNonce(sender), BigInteger.ZERO, data, 2_000_00, 1);
        return avm.run(kernel, new Transaction[] { tx }, executionType, commonMainchainBlockNumber)[0].getResult();
    }
}

19 Source : PersistanceNameMappingTest.java
with MIT License
from aionnetwork

private void runTestLogic(AvmImpl avm) {
    kernel.generateBlock();
    // Deploy the contract.
    AionAddress contract = deployContract(avm, kernel);
    kernel.generateBlock();
    // Set all the persistant fields.
    callContract(avm, kernel, contract, "setFields");
    kernel.generateBlock();
    // Verify all the persistant fields have been retained.
    callContract(avm, kernel, contract, "verifyFields");
}

19 Source : PerformanceTest.java
with MIT License
from aionnetwork

public clreplaced PerformanceTest {

    // NOTE:  Output is ONLY produced if REPORT is set to true.
    private static final boolean REPORT = false;

    private TestingState kernel;

    private AvmImpl avm;

    private static final int transactionBlockSize = 10;

    private static final int contextNum = 3;

    // We want to use the same number for single and batched calls.
    private static final int userDappNum = transactionBlockSize * contextNum;

    private static final int heavyLevel = 1;

    private static final int allocSize = (1 * (1 << 20));

    private static long energyLimit = 1_000_000_000_000_000l;

    private static long energyPrice = 1l;

    private AionAddress[] userAddrs = new AionAddress[userDappNum];

    private AionAddress[] contractAddrs = new AionAddress[userDappNum];

    @Before
    public void setup() {
        this.avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
        TestingBlock block = new TestingBlock(new byte[32], 1, Helpers.randomAddress(), System.currentTimeMillis(), new byte[0]);
        this.kernel = new TestingState(block);
        deploy();
    }

    /**
     * Creating a lot of random userAddrs and the same number of dapps of performance test.
     */
    public void deploy() {
        long startTime = System.currentTimeMillis();
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(PerformanceTestTarget.clreplaced);
        byte[] args = ABIEncoder.encodeOneIntegerArray(new int[] { heavyLevel, allocSize });
        byte[] txData = new CodeAndArguments(jar, args).encodeToBytes();
        // Deploy
        for (int i = 0; i < userDappNum; ++i) {
            // creating users
            AionAddress userAddress = Helpers.randomAddress();
            kernel.createAccount(userAddress);
            kernel.adjustBalance(userAddress, BigInteger.TEN.pow(18));
            userAddrs[i] = userAddress;
            // deploying dapp
            Transaction create = AvmTransactionUtil.create(userAddress, kernel.getNonce(userAddress), BigInteger.ZERO, txData, energyLimit, energyPrice);
            TransactionResult createResult = avm.run(this.kernel, new Transaction[] { create }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
            replacedert.replacedertTrue(createResult.transactionStatus.isSuccess());
            AionAddress contractAddr = new AionAddress(createResult.copyOfTransactionOutput().orElseThrow());
            contractAddrs[i] = contractAddr;
        }
        long endTime = System.currentTimeMillis();
        long timeElapsed = endTime - startTime;
        if (REPORT) {
            System.out.printf("deploy: %d ms\n", timeElapsed);
        }
    }

    @After
    public void tearDown() {
        this.avm.shutdown();
    }

    @Test
    public void testPerformanceCpuNto1Single() throws Exception {
        performanceTestSingle("cpuHeavy", true, "testPerformanceCpuNto1Single");
    }

    @Test
    public void testPerformanceCpuNtoNSingle() throws Exception {
        performanceTestSingle("cpuHeavy", false, "testPerformanceCpuNtoNSingle");
    }

    @Test
    public void testPerformanceMemoryNto1Single() throws Exception {
        performanceTestSingle("memoryHeavy", true, "testPerformanceMemoryNto1Single");
    }

    @Test
    public void testPerformanceMemoryNtoNSingle() throws Exception {
        performanceTestSingle("memoryHeavy", false, "testPerformanceMemoryNtoNSingle");
    }

    public void performanceTestSingle(String methodName, boolean Nto1, String testName) {
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < userDappNum; ++i) {
            callSingle(userAddrs[i], Nto1 ? contractAddrs[0] : contractAddrs[i], methodName);
        }
        long endTime = System.currentTimeMillis();
        long timeElapsed = endTime - startTime;
        if (REPORT) {
            System.out.printf("%s: %d ms\n", testName, timeElapsed);
        }
    }

    private void callSingle(AionAddress sender, AionAddress contractAddr, String methodName) {
        byte[] argData = new ABIStreamingEncoder().encodeOneString(methodName).toBytes();
        Transaction call = AvmTransactionUtil.call(sender, contractAddr, kernel.getNonce(sender), BigInteger.ZERO, argData, energyLimit, energyPrice);
        TransactionResult result = avm.run(this.kernel, new Transaction[] { call }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
        replacedert.replacedertTrue(result.transactionStatus.isSuccess());
    }

    /**
     * One transaction context contains a lot of transactions.
     */
    @Test
    public void testPerformanceCpuNto1Batch() throws Exception {
        performanceBatch("cpuHeavy", true, "testPerformanceCpuNto1Batch");
    }

    @Test
    public void testPerformanceCpuNtoNBatch() throws Exception {
        performanceBatch("cpuHeavy", false, "testPerformanceCpuNtoNBatch");
    }

    @Test
    public void testPerformanceMemoryNto1Batch() throws Exception {
        performanceBatch("memoryHeavy", true, "testPerformanceMemoryNto1Batch");
    }

    @Test
    public void testPerformanceMemoryNtoNBatch() throws Exception {
        performanceBatch("memoryHeavy", false, "testPerformanceMemoryNtoNBatch");
    }

    public void performanceBatch(String methodName, boolean Nto1, String testName) {
        long startTime = System.currentTimeMillis();
        callBatch(methodName, Nto1);
        long endTime = System.currentTimeMillis();
        long timeElapsed = endTime - startTime;
        if (REPORT) {
            System.out.printf("%s: %d ms\n", testName, timeElapsed);
        }
    }

    public void callBatch(String methodName, boolean Nto1) {
        byte[] argData = new ABIStreamingEncoder().encodeOneString(methodName).toBytes();
        for (int j = 0; j < contextNum; ++j) {
            Transaction[] transactionArray = new Transaction[transactionBlockSize];
            for (int i = 0; i < transactionBlockSize; ++i) {
                AionAddress sender = userAddrs[i];
                AionAddress contractAddr = Nto1 ? contractAddrs[0] : contractAddrs[i];
                transactionArray[i] = AvmTransactionUtil.call(sender, contractAddr, kernel.getNonce(sender), BigInteger.ZERO, argData, energyLimit, energyPrice);
            }
            FutureResult[] futures = avm.run(this.kernel, transactionArray, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1);
            for (FutureResult future : futures) {
                TransactionResult result = future.getResult();
                replacedert.replacedertTrue(result.transactionStatus.isSuccess());
                // These should all return an empty byte[] (void).
                replacedert.replacedertEquals(0, result.copyOfTransactionOutput().orElseThrow().length);
            }
        }
    }
}

19 Source : ExceptionWrappingIntegrationTest.java
with MIT License
from aionnetwork

private int callReturnInt(TestingBlock block, TestingState kernel, AvmImpl avm, AionAddress contractAddr, String methodName) {
    byte[] result = commonSuccessCall(block, kernel, avm, contractAddr, methodName);
    return new ABIDecoder(result).decodeOneInteger();
}

19 Source : ExceptionWrappingIntegrationTest.java
with MIT License
from aionnetwork

private byte[] callReturnByteArray(TestingBlock block, TestingState kernel, AvmImpl avm, AionAddress contractAddr, String methodName) {
    byte[] result = commonSuccessCall(block, kernel, avm, contractAddr, methodName);
    return new ABIDecoder(result).decodeOneByteArray();
}

19 Source : EnergyUsageDebugModeTest.java
with MIT License
from aionnetwork

/**
 * Difference of energy consumption explained more in issue-345
 */
public clreplaced EnergyUsageDebugModeTest {

    private static TestingState kernel;

    private static AionAddress deployer = TestingState.PREMINED_ADDRESS;

    @BeforeClreplaced
    public static void setup() {
        TestingBlock block = new TestingBlock(new byte[32], 1, Helpers.randomAddress(), System.currentTimeMillis(), new byte[0]);
        kernel = new TestingState(block);
    }

    /**
     * since the debug mode's code blocks are smaller than the normal mode, the energy consumed after throwing an exception (in debug mode) is less
     */
    @Test
    public void testEnergyConsumptionDivisionFunction() {
        long debugEnergyUsageDivision = testEnergyUsedInDebugMode(10, 0);
        long normalEnergyUsageDivision = testEnergyUsedInNormalMode(10, 0);
        replacedertTrue(debugEnergyUsageDivision < normalEnergyUsageDivision);
    }

    /**
     * since the debug mode's code blocks are smaller, only what is executed will be billed.
     * Thus the faster the exception is thrown, the lower the energy consumption.
     */
    @Test
    public void testEnergyConsumptionInDebug() {
        long debugEnergyUsageFailEarly = testEnergyUsedInDebugMode(10, 0);
        long debugEnergyUsageFailLate = testEnergyUsedInDebugMode(0, 10);
        replacedertTrue(debugEnergyUsageFailEarly < debugEnergyUsageFailLate);
    }

    private long testEnergyUsedInDebugMode(int a, int b) {
        AvmConfiguration config = new AvmConfiguration();
        config.preserveDebuggability = true;
        config.enableVerboseContractErrors = true;
        AvmImpl avmDebugMode = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), config);
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(EnergyUsageDebugModeTarget.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        long energyPrice = 1l;
        // deploy in debugMode Mode
        Transaction create = AvmTransactionUtil.create(deployer, kernel.getNonce(deployer), BigInteger.ZERO, txData, 10_000_000l, energyPrice);
        TransactionResult createResult = avmDebugMode.run(kernel, new Transaction[] { create }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
        replacedert.replacedertTrue(createResult.transactionStatus.isSuccess());
        AionAddress contractAddressDebug = new AionAddress(createResult.copyOfTransactionOutput().orElseThrow());
        long energyLimit = 1_000_000l;
        byte[] argData = encodeTryToDivideInteger(a, b);
        Transaction call = AvmTransactionUtil.call(deployer, contractAddressDebug, kernel.getNonce(deployer), BigInteger.ZERO, argData, energyLimit, 1l);
        TransactionResult result = avmDebugMode.run(kernel, new Transaction[] { call }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
        replacedert.replacedertTrue(result.transactionStatus.isSuccess());
        replacedert.replacedertEquals(111, new BigInteger(result.copyOfTransactionOutput().orElseThrow()).intValue());
        avmDebugMode.shutdown();
        return result.energyUsed;
    }

    private long testEnergyUsedInNormalMode(int a, int b) {
        AvmImpl avmNormalMode = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(EnergyUsageDebugModeTarget.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        long energyLimit = 1_000_000l;
        long energyPrice = 1l;
        // deploy in normal Mode
        Transaction create = AvmTransactionUtil.create(deployer, kernel.getNonce(deployer), BigInteger.ZERO, txData, 10_000_000l, energyPrice);
        TransactionResult createResult = avmNormalMode.run(kernel, new Transaction[] { create }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
        replacedert.replacedertTrue(createResult.transactionStatus.isSuccess());
        AionAddress contractAddressNormal = new AionAddress(createResult.copyOfTransactionOutput().orElseThrow());
        byte[] argData = encodeTryToDivideInteger(a, b);
        Transaction call = AvmTransactionUtil.call(deployer, contractAddressNormal, kernel.getNonce(deployer), BigInteger.ZERO, argData, energyLimit, 1l);
        TransactionResult result = avmNormalMode.run(kernel, new Transaction[] { call }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
        replacedert.replacedertTrue(result.transactionStatus.isSuccess());
        replacedert.replacedertEquals(111, new BigInteger(result.copyOfTransactionOutput().orElseThrow()).intValue());
        avmNormalMode.shutdown();
        return result.energyUsed;
    }

    private static byte[] encodeTryToDivideInteger(int a, int b) {
        return new ABIStreamingEncoder().encodeOneString("tryToDivideInteger").encodeOneInteger(a).encodeOneInteger(b).toBytes();
    }
}

19 Source : ConstantLoadingIntegrationTest.java
with MIT License
from aionnetwork

@Test
public void testPersistence() throws Exception {
    AionAddress contractAddr = deploy();
    // Run the creation and then test the read calls.
    callStatic(contractAddr, 0);
    callStatic(contractAddr, 1);
    int bareHash = 64;
    int bareLength = 6;
    int populateHash = 67;
    int populateLength = 3;
    byte[] bare = callStatic(contractAddr, 2);
    byte[] populated = callStatic(contractAddr, 3);
    replacedert.replacedertEquals((byte) bareHash, bare[0]);
    replacedert.replacedertEquals((byte) bareLength, bare[1]);
    replacedert.replacedertEquals((byte) populateHash, populated[0]);
    replacedert.replacedertEquals((byte) populateLength, populated[1]);
}

19 Source : ConstantLoadingIntegrationTest.java
with MIT License
from aionnetwork

@Test
public void testCreation() throws Exception {
    AionAddress contractAddr = deploy();
    // Test just the creation modes.
    int bareHash = 64;
    int bareLength = 6;
    int populateHash = 67;
    int populateLength = 3;
    byte[] bare = callStatic(contractAddr, 0);
    byte[] populated = callStatic(contractAddr, 1);
    replacedert.replacedertEquals((byte) bareHash, bare[0]);
    replacedert.replacedertEquals((byte) bareLength, bare[1]);
    replacedert.replacedertEquals((byte) populateHash, populated[0]);
    replacedert.replacedertEquals((byte) populateLength, populated[1]);
}

19 Source : ConstantBillingTest.java
with MIT License
from aionnetwork

public clreplaced ConstantBillingTest {

    private static AionAddress deployer = TestingState.PREMINED_ADDRESS;

    private static long energyLimit = 1_000_000;

    @Test
    public void test() {
        byte[] jar = JarBuilder.buildJarForMainClreplacedAndExplicitClreplacedNamesAndBytecode(ConstantBillingTarget.clreplaced, Collections.emptyMap());
        AvmImpl avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
        TestingBlock block = new TestingBlock(new byte[32], 1, Helpers.randomAddress(), System.currentTimeMillis(), new byte[0]);
        IExternalState externalState = new TestingState(block);
        Transaction tx = AvmTransactionUtil.create(deployer, externalState.getNonce(deployer), BigInteger.ZERO, new CodeAndArguments(jar, new byte[0]).encodeToBytes(), energyLimit, 1);
        TransactionResult result = avm.run(externalState, new Transaction[] { tx }, ExecutionType.replacedUME_MAINCHAIN, externalState.getBlockNumber() - 1)[0].getResult();
        replacedertTrue(result.transactionStatus.isSuccess());
        BytecodeFeeScheduler feeScheduler = new BytecodeFeeScheduler();
        feeScheduler.initialize();
        // See AKI-136: static instrumentation code is no longer billed, so we charge for an ldc + putstatic in the clinit now (replacedigning constant to static field)
        // rather than a getstatic + putstatic (fetching the constant from our constant instrumentation clreplaced)
        long ldcFee = feeScheduler.getFee(Opcodes.LDC);
        long putstaticFee = feeScheduler.getFee(Opcodes.PUTSTATIC);
        long returnFee = feeScheduler.getFee(Opcodes.RETURN);
        long clinitCost = ldcFee + putstaticFee + returnFee;
        long basicTransactionCost = BillingRules.getBasicTransactionCost(tx.copyOfTransactionData());
        long deploymentFee = BillingRules.getDeploymentFee(1, jar.length);
        long storageFee = 141;
        long cost = basicTransactionCost + deploymentFee + clinitCost + storageFee;
        replacedertEquals(cost, result.energyUsed);
        avm.shutdown();
    }
}

19 Source : AionCollectionPerfTest.java
with MIT License
from aionnetwork

public clreplaced AionCollectionPerfTest {

    // NOTE:  Output is ONLY produced if REPORT is set to true.
    private static final boolean REPORT = false;

    private AionAddress from = TestingState.PREMINED_ADDRESS;

    private TestingBlock block = new TestingBlock(new byte[32], 1, Helpers.randomAddress(), System.currentTimeMillis(), new byte[0]);

    private long energyLimit = 100_000_000L;

    private long energyPrice = 1;

    private byte[] buildListPerfJar() {
        return UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(AionListPerfContract.clreplaced);
    }

    private byte[] buildSetPerfJar() {
        return UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(AionSetPerfContract.clreplaced);
    }

    private byte[] buildMapPerfJar() {
        return UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(AionMapPerfContract.clreplaced);
    }

    private TransactionResult deploy(IExternalState externalState, AvmImpl avm, byte[] testJar) {
        byte[] testWalletArguments = new byte[0];
        Transaction createTransaction = AvmTransactionUtil.create(from, externalState.getNonce(from), BigInteger.ZERO, new CodeAndArguments(testJar, testWalletArguments).encodeToBytes(), energyLimit, energyPrice);
        TransactionResult createResult = avm.run(externalState, new Transaction[] { createTransaction }, ExecutionType.replacedUME_MAINCHAIN, externalState.getBlockNumber() - 1)[0].getResult();
        replacedert.replacedertTrue(createResult.transactionStatus.isSuccess());
        return createResult;
    }

    private TransactionResult call(IExternalState externalState, AvmImpl avm, AionAddress contract, AionAddress sender, byte[] args) {
        Transaction callTransaction = AvmTransactionUtil.call(sender, contract, externalState.getNonce(sender), BigInteger.ZERO, args, energyLimit, 1l);
        TransactionResult callResult = avm.run(externalState, new Transaction[] { callTransaction }, ExecutionType.replacedUME_MAINCHAIN, externalState.getBlockNumber() - 1)[0].getResult();
        replacedert.replacedertTrue(callResult.transactionStatus.isSuccess());
        return callResult;
    }

    @Test
    public void testList() {
        report(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
        report(">> Energy measurement for AionList");
        byte[] args;
        IExternalState externalState = new TestingState(block);
        AvmImpl avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
        TransactionResult deployRes = deploy(externalState, avm, buildListPerfJar());
        AionAddress contract = new AionAddress(deployRes.copyOfTransactionOutput().orElseThrow());
        args = encodeNoArgsMethodCall("callInit");
        TransactionResult initResult = call(externalState, avm, contract, from, args);
        replacedert.replacedertTrue(initResult.transactionStatus.isSuccess());
        args = encodeNoArgsMethodCall("callAppend");
        TransactionResult appendResult = call(externalState, avm, contract, from, args);
        report(">> Append        : " + appendResult.energyUsed / AionListPerfContract.SIZE);
        args = encodeNoArgsMethodCall("callInit");
        call(externalState, avm, contract, from, args);
        args = encodeNoArgsMethodCall("callInsertHead");
        TransactionResult insertHeadResult = call(externalState, avm, contract, from, args);
        report(">> Insert Head   : " + insertHeadResult.energyUsed / AionListPerfContract.SIZE);
        args = encodeNoArgsMethodCall("callInit");
        call(externalState, avm, contract, from, args);
        args = encodeNoArgsMethodCall("callInsertMiddle");
        TransactionResult insertMiddleResult = call(externalState, avm, contract, from, args);
        report(">> Insert Middle : " + insertMiddleResult.energyUsed / AionListPerfContract.SIZE);
        report("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
        avm.shutdown();
    }

    @Test
    public void testSet() {
        report(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
        report(">> Energy measurement for AionSet");
        byte[] args;
        IExternalState externalState = new TestingState(block);
        AvmImpl avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
        TransactionResult deployRes = deploy(externalState, avm, buildSetPerfJar());
        AionAddress contract = new AionAddress(deployRes.copyOfTransactionOutput().orElseThrow());
        args = encodeNoArgsMethodCall("callInit");
        TransactionResult initResult = call(externalState, avm, contract, from, args);
        replacedert.replacedertTrue(initResult.transactionStatus.isSuccess());
        args = encodeNoArgsMethodCall("callAdd");
        TransactionResult addResult = call(externalState, avm, contract, from, args);
        report(">> Add           : " + addResult.energyUsed / AionSetPerfContract.SIZE);
        args = encodeNoArgsMethodCall("callContains");
        TransactionResult containsResult = call(externalState, avm, contract, from, args);
        report(">> Contains      : " + containsResult.energyUsed / AionSetPerfContract.SIZE);
        args = encodeNoArgsMethodCall("callRemove");
        TransactionResult removeReult = call(externalState, avm, contract, from, args);
        report(">> Remove        : " + removeReult.energyUsed / AionSetPerfContract.SIZE);
        report("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
        report(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
        report(">> Energy measurement for AionPlainSet");
        args = encodeNoArgsMethodCall("callInitB");
        initResult = call(externalState, avm, contract, from, args);
        args = encodeNoArgsMethodCall("callAddB");
        addResult = call(externalState, avm, contract, from, args);
        report(">> Add           : " + addResult.energyUsed / AionSetPerfContract.SIZE);
        args = encodeNoArgsMethodCall("callContainsB");
        containsResult = call(externalState, avm, contract, from, args);
        report(">> Contains      : " + containsResult.energyUsed / AionSetPerfContract.SIZE);
        args = encodeNoArgsMethodCall("callRemoveB");
        removeReult = call(externalState, avm, contract, from, args);
        report(">> Remove        : " + removeReult.energyUsed / AionSetPerfContract.SIZE);
        report("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
        avm.shutdown();
    }

    @Test
    public void testMap() {
        report(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
        report(">> Energy measurement for AionMap");
        byte[] args;
        IExternalState externalState = new TestingState(block);
        AvmImpl avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
        TransactionResult deployRes = deploy(externalState, avm, buildMapPerfJar());
        AionAddress contract = new AionAddress(deployRes.copyOfTransactionOutput().orElseThrow());
        args = encodeNoArgsMethodCall("callInit");
        TransactionResult initResult = call(externalState, avm, contract, from, args);
        replacedert.replacedertTrue(initResult.transactionStatus.isSuccess());
        args = encodeNoArgsMethodCall("callPut");
        TransactionResult putResult = call(externalState, avm, contract, from, args);
        report(">> Put           : " + putResult.energyUsed / AionMapPerfContract.SIZE);
        args = encodeNoArgsMethodCall("callGet");
        TransactionResult getResult = call(externalState, avm, contract, from, args);
        report(">> Get           : " + getResult.energyUsed / AionMapPerfContract.SIZE);
        args = encodeNoArgsMethodCall("callRemove");
        TransactionResult removeResult = call(externalState, avm, contract, from, args);
        report(">> Remove        : " + removeResult.energyUsed / AionMapPerfContract.SIZE);
        report("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
        report(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
        report(">> Energy measurement for AionPlainMap");
        args = encodeNoArgsMethodCall("callInitB");
        initResult = call(externalState, avm, contract, from, args);
        args = encodeNoArgsMethodCall("callPutB");
        putResult = call(externalState, avm, contract, from, args);
        report(">> Put           : " + putResult.energyUsed / AionMapPerfContract.SIZE);
        args = encodeNoArgsMethodCall("callGetB");
        getResult = call(externalState, avm, contract, from, args);
        report(">> Get           : " + getResult.energyUsed / AionMapPerfContract.SIZE);
        args = encodeNoArgsMethodCall("callRemoveB");
        removeResult = call(externalState, avm, contract, from, args);
        report(">> Remove        : " + removeResult.energyUsed / AionMapPerfContract.SIZE);
        report("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
        avm.shutdown();
    }

    private static byte[] encodeNoArgsMethodCall(String methodName) {
        return new ABIStreamingEncoder().encodeOneString(methodName).toBytes();
    }

    private static void report(String output) {
        if (REPORT) {
            System.out.println(output);
        }
    }
}

19 Source : ContractBalanceTest.java
with MIT License
from aionnetwork

private Address getContractAsAbiAddress(AionAddress contract) {
    return new Address(contract.toByteArray());
}

19 Source : AvmImplTest.java
with MIT License
from aionnetwork

public clreplaced AvmImplTest {

    private static AionAddress deployer = TestingState.PREMINED_ADDRESS;

    private static TestingBlock block;

    @Rule
    public TemporaryFolder folder = new TemporaryFolder();

    @BeforeClreplaced
    public static void setupClreplaced() {
        block = new TestingBlock(new byte[32], 1, Helpers.randomAddress(), System.currentTimeMillis(), new byte[0]);
    }

    @Test
    public void testStateUpdates() {
        TestingState kernel = new TestingState(block);
        AvmImpl avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
        AionAddress from = deployer;
        AionAddress to = new AionAddress(new byte[32]);
        BigInteger value = BigInteger.valueOf(1000L);
        byte[] data = "data".getBytes();
        long energyLimit = 50_000L;
        long energyPrice = 1L;
        Transaction tx = AvmTransactionUtil.call(from, to, kernel.getNonce(from), value, data, energyLimit, energyPrice);
        TransactionResult result = avm.run(kernel, new Transaction[] { tx }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
        // verify results
        replacedertTrue(result.transactionStatus.isSuccess());
        replacedertFalse(result.copyOfTransactionOutput().isPresent());
        replacedertEquals(BillingRules.getBasicTransactionCost(tx.copyOfTransactionData()), result.energyUsed);
        replacedertEquals(0, result.logs.size());
        replacedertEquals(0, result.internalTransactions.size());
        // verify state change
        replacedertEquals(1, kernel.getNonce(from).intValue());
        replacedertEquals(TestingState.PREMINED_AMOUNT.subtract(value).subtract(BigInteger.valueOf(BillingRules.getBasicTransactionCost(tx.copyOfTransactionData()) * energyPrice)), kernel.getBalance(deployer));
        replacedertEquals(0, kernel.getNonce(to).intValue());
        replacedertEquals(value, kernel.getBalance(to));
        avm.shutdown();
    }

    @Test(expected = IllegalArgumentException.clreplaced)
    public void testTransactionWithoutSignBytes() {
        TestingState kernel = new TestingState(block);
        AionAddress from = deployer;
        AionAddress to = new AionAddress(new byte[32]);
        // large value that caused issues when not specifically interpreted as a positive integer
        BigInteger value = BigInteger.valueOf(13).multiply(BigInteger.TEN.pow(18));
        byte[] data = new byte[0];
        long energyLimit = 50_000L;
        long energyPrice = 1L;
        // Verifies that we cannot create a transaction with a negative nonce/value.
        AvmTransactionUtil.call(from, to, new BigInteger(omitSignByte(kernel.getNonce(from).toByteArray())), new BigInteger(omitSignByte(value.toByteArray())), data, energyLimit, energyPrice);
    }

    /**
     * Omits sign indication byte. Used by the Aion kernel.
     */
    public static byte[] omitSignByte(byte[] data) {
        if (data == null) {
            return null;
        }
        if (data.length != 1 && data[0] == 0) {
            byte[] tmp = new byte[data.length - 1];
            System.arraycopy(data, 1, tmp, 0, tmp.length);
            data = tmp;
        }
        return data;
    }

    @Test
    public void checkMainClreplacedHasProperName() throws IOException {
        byte[] jar = JarBuilder.buildJarForMainClreplacedAndExplicitClreplacedNamesAndBytecode(MainClreplaced.clreplaced, Collections.emptyMap());
        final RawDappModule dappModule = RawDappModule.readFromJar(jar, false, true);
        final String mainClreplacedName = MainClreplaced.clreplaced.getName();
        replacedertEquals(mainClreplacedName, dappModule.mainClreplaced);
        Map<String, byte[]> clreplacedes = dappModule.clreplacedes;
        replacedertEquals(1, clreplacedes.size());
    }

    @Test
    public void testJvmError() {
        // Note that we eventually need to test how this interacts with AvmImpl's contract entry-point but this at least proves
        // that the hierarchy is correctly put together.
        String result = null;
        try {
            throw new JvmError(new UnknownError("testing"));
        } catch (AvmThrowable e) {
            result = e.getMessage();
        }
        replacedertEquals("java.lang.UnknownError: testing", result);
    }

    /**
     * Tests that, if we hit the energy limit, we continue to hit it on every attempt to charge for a new code block.
     */
    @Test
    public void testPersistentEnergyLimit() {
        // Set up the runtime (note that we need to initialize the NodeEnvironment before we attach to the thread)..
        Map<String, byte[]> contractClreplacedes = Helpers.mapIncludingHelperBytecode(Collections.emptyMap(), Helpers.loadDefaultHelperBytecode());
        AvmClreplacedLoader avmClreplacedLoader = NodeEnvironment.singleton.createInvocationClreplacedLoader(contractClreplacedes);
        IRuntimeSetup runtimeSetup = new Helper();
        IInstrumentation instrumentation = new CommonInstrumentation();
        InstrumentationHelpers.attachThread(instrumentation);
        InstrumentationHelpers.pushNewStackFrame(runtimeSetup, avmClreplacedLoader, 5L, 1, null);
        // Prove that we can charge 0 without issue.
        instrumentation.chargeEnergy(0);
        replacedertEquals(5, instrumentation.energyLeft());
        // Run the test.
        int catchCount = 0;
        OutOfEnergyException error = null;
        try {
            instrumentation.chargeEnergy(10);
        } catch (OutOfEnergyException e) {
            catchCount += 1;
            error = e;
        }
        // We didn't reset the state so this should still fail.
        try {
            instrumentation.chargeEnergy(0);
        } catch (OutOfEnergyException e) {
            catchCount += 1;
            // And have the same exception.
            replacedertEquals(error, e);
        }
        replacedertEquals(2, catchCount);
        InstrumentationHelpers.popExistingStackFrame(runtimeSetup);
        InstrumentationHelpers.detachThread(instrumentation);
    }

    @Test
    public void testHelperStateRestore() {
        byte[] jar = JarBuilder.buildJarForMainClreplacedAndExplicitClreplacedNamesAndBytecode(AvmImplTestResource.clreplaced, Collections.emptyMap());
        byte[] arguments = new byte[0];
        byte[] txData = new CodeAndArguments(jar, arguments).encodeToBytes();
        TestingState kernel = new TestingState(block);
        AvmImpl avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
        // deploy
        long energyLimit = 1_000_000l;
        long energyPrice = 1l;
        Transaction tx1 = AvmTransactionUtil.create(deployer, kernel.getNonce(deployer), BigInteger.ZERO, txData, energyLimit, energyPrice);
        TransactionResult result1 = avm.run(kernel, new Transaction[] { tx1 }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
        replacedertTrue(result1.transactionStatus.isSuccess());
        AionAddress contractAddr = new AionAddress(result1.copyOfTransactionOutput().orElseThrow());
        // Account for the cost:  deployment, clinit, init call.
        long basicCost = BillingRules.getBasicTransactionCost(txData);
        long codeInstantiationOfDeploymentFee = BillingRules.getDeploymentFee(1, jar.length);
        // Note that the only <clinit> is in the generated constants clreplaced, which is free.
        long clinitCost = 0L;
        long initialStorageCost = 222;
        long transactionCost = basicCost + codeInstantiationOfDeploymentFee + clinitCost + initialStorageCost;
        replacedertEquals(transactionCost, result1.energyUsed);
        // call (1 -> 2 -> 2)
        long transaction2EnergyLimit = 1_000_000l;
        Transaction tx2 = AvmTransactionUtil.call(deployer, contractAddr, kernel.getNonce(deployer), BigInteger.ZERO, contractAddr.toByteArray(), transaction2EnergyLimit, energyPrice);
        TransactionResult result2 = avm.run(kernel, new Transaction[] { tx2 }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
        replacedertTrue(result2.transactionStatus.isSuccess());
        replacedertArrayEquals("CALL".getBytes(), result2.copyOfTransactionOutput().orElseThrow());
        // Account for the cost:  (blocks in call method) + runtime.call
        // code block cost for initial call
        long costOfBlocks = 51l + 31l + 333l;
        // reentrant call cost including code block cost
        long costOfRuntimeCall = 51l + 31l + 61l + (100 + 630);
        // All persistence load/store cost (note that this is a reentrant call): (2 reads at 74, 2 writes at 222)
        long runStorageCost = 74 + 74 + 222 + 222;
        // runtime cost of the initial call
        long runtimeCost = 100 + 100 + 300 + 100 + 300 + 5000 + 620;
        transactionCost = runtimeCost + BillingRules.getBasicTransactionCost(tx2.copyOfTransactionData()) + costOfBlocks + costOfRuntimeCall + runStorageCost;
        // NOTE: the numbers are not calculated, but for fee schedule change detection.
        replacedertEquals(transactionCost, result2.energyUsed);
        avm.shutdown();
    }

    @Test
    public void testNullReturnCrossCall() {
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(ReentrantCrossCallResource.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        TestingState kernel = new TestingState(block);
        AvmImpl avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
        // deploy
        AionAddress contractAddr = createDApp(kernel, avm, txData);
        // Call the callSelfForNull entry-point and it should return null to us.
        byte[] argData = encodeNoArgCall("callSelfForNull");
        callDAppVoid(kernel, avm, contractAddr, argData);
        avm.shutdown();
    }

    @Test
    public void testRecursiveHashCode() {
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(ReentrantCrossCallResource.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        TestingState kernel = new TestingState(block);
        AvmImpl avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
        // deploy
        long energyLimit = 10_000_000l;
        AionAddress contractAddr = createDApp(kernel, avm, txData);
        // Try a few invocations of different depths, bearing in mind the change of nextHashCode between each invocation.
        // We will do 2 zero-depth calls to see the delta between the 2 calls.
        // Then, we will do an indirect call and verify that the delta is greater.
        // If the hashcode wasn't restored across reentrant calls, this wouldn't be greater as it wouldn't capture the small cost of the original
        // indirect call (since we create at least 1 object in that path).
        int zero0 = callRecursiveHash(kernel, avm, energyLimit, contractAddr, 0);
        int zero1 = callRecursiveHash(kernel, avm, energyLimit, contractAddr, 0);
        int zero2 = callRecursiveHash(kernel, avm, energyLimit, contractAddr, 0);
        int one0 = callRecursiveHash(kernel, avm, energyLimit, contractAddr, 1);
        int one1 = callRecursiveHash(kernel, avm, energyLimit, contractAddr, 1);
        int one2 = callRecursiveHash(kernel, avm, energyLimit, contractAddr, 1);
        replacedertEquals(zero1 - zero0, zero2 - zero1);
        replacedertEquals(one1 - one0, one2 - one1);
        replacedertTrue((one1 - one0) > (zero1 - zero0));
        avm.shutdown();
    }

    /**
     * Tests that reentrant calls do have detectable side-effects within the caller's space, when they commit.
     */
    @Test
    public void testCommitReentrantCalls() {
        boolean shouldFail = false;
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(ReentrantCrossCallResource.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        TestingState kernel = new TestingState(block);
        AvmImpl avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
        // deploy
        AionAddress contractAddr = createDApp(kernel, avm, txData);
        // Get direct increments from 1 to 2 and returns 2.
        replacedertEquals(2, callReentrantAccess(kernel, avm, contractAddr, "getDirect", shouldFail));
        // Get near increments from 1 to 2 and returns 2.
        replacedertEquals(2, callReentrantAccess(kernel, avm, contractAddr, "getNear", shouldFail));
        // Get far increments from 1 to 2 and returns 2.
        replacedertEquals(2, callReentrantAccess(kernel, avm, contractAddr, "getFar", shouldFail));
        // Get near increments from 2 to 3 and returns 3.
        replacedertEquals(3, callReentrantAccess(kernel, avm, contractAddr, "getNear", shouldFail));
        avm.shutdown();
    }

    /**
     * Tests that reentrant calls do NOT have detectable side-effects within the caller's space, when they rollback.
     */
    @Test
    public void testRollbackReentrantCalls() {
        boolean shouldFail = true;
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(ReentrantCrossCallResource.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        TestingState kernel = new TestingState(block);
        AvmImpl avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
        // deploy
        AionAddress contractAddr = createDApp(kernel, avm, txData);
        // We expect these to all fail, so they should be left with the initial values:  1.
        replacedertEquals(1, callReentrantAccess(kernel, avm, contractAddr, "getDirect", shouldFail));
        replacedertEquals(1, callReentrantAccess(kernel, avm, contractAddr, "getNear", shouldFail));
        replacedertEquals(1, callReentrantAccess(kernel, avm, contractAddr, "getFar", shouldFail));
        replacedertEquals(1, callReentrantAccess(kernel, avm, contractAddr, "getNear", shouldFail));
        avm.shutdown();
    }

    /**
     * Tests that reentrant calls do not accidentally write-back the statics, even when the caller fails.
     */
    @Test
    public void testRollbackAfterReentrantSuccess() {
        boolean shouldFail = true;
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(ReentrantCrossCallResource.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        TestingState kernel = new TestingState(block);
        AvmImpl avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
        // deploy
        long energyLimit = 1_000_000l;
        AionAddress contractAddr = createDApp(kernel, avm, txData);
        // Cause the failure.
        byte[] nearData = encodeNoArgCall("localFailAfterReentrant");
        Transaction tx = AvmTransactionUtil.call(deployer, contractAddr, kernel.getNonce(deployer), BigInteger.ZERO, nearData, energyLimit, 1L);
        TransactionResult result2 = avm.run(kernel, new Transaction[] { tx }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
        replacedertEquals(AvmInternalError.FAILED_OUT_OF_ENERGY.error, result2.transactionStatus.causeOfError);
        // We shouldn't see any changes, since this failed.
        // We expect these to all fail, so they should be left with the initial values:  1.
        replacedertEquals(1, callReentrantAccess(kernel, avm, contractAddr, "getDirect", shouldFail));
        replacedertEquals(1, callReentrantAccess(kernel, avm, contractAddr, "getNear", shouldFail));
        replacedertEquals(1, callReentrantAccess(kernel, avm, contractAddr, "getFar", shouldFail));
        replacedertEquals(1, callReentrantAccess(kernel, avm, contractAddr, "getNear", shouldFail));
        avm.shutdown();
    }

    /**
     * Tests that reentrant calls do not leave any side-effects within the caller's space when the rollback only during the last part of write-back.
     */
    @Test
    public void testReentrantRollbackDuringCommit() {
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(ReentrantCrossCallResource.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        TestingState kernel = new TestingState(block);
        AvmImpl avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
        // deploy
        AionAddress contractAddr = createDApp(kernel, avm, txData);
        // We just want to call our special getFar helper with a constrained energy.
        // WARNING:  This test is very sensitive to storage billing configuration so the energy limit likely needs to be updated when that changes.
        // The write-back of the callee attempts to write statics and 2 instances.  We want it to fail at 1 instance (14_400L seems to do this).
        long failingLimit = 14_400L;
        byte[] callData = encodeCallLong("getFarWithEnergy", failingLimit);
        boolean result = callDAppBoolean(kernel, avm, contractAddr, callData);
        // This returns false since the value didn't change,
        replacedertEquals(false, result);
        avm.shutdown();
    }

    /**
     * Tests that inner clreplacedes are correctly handled by reentrant calls.
     * Also ensures that instances reachable from statics are correctly handled to arbitrary recursive depth.
     */
    @Test
    public void testReentrantRecursiveNested() {
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(ReentrantCrossCallResource.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        TestingState kernel = new TestingState(block);
        AvmImpl avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
        // deploy
        AionAddress contractAddr = createDApp(kernel, avm, txData);
        // We just want to call our special getFar helper with a constrained energy.
        // WARNING:  This test is very sensitive to storage billing configuration so the energy limit likely needs to be updated when that changes.
        // The write-back of the callee attempts to write statics and 2 instances.  We want it to fail at 1 instance (20_000L seems to do this).
        byte[] callData = encodeCallIntInt("recursiveChangeNested", 0, 5);
        int result = callDAppInteger(kernel, avm, contractAddr, callData);
        // We don't want to depend on a specific hashcode (appears to be 19) but just the idea that it needs to be non-zero.
        replacedertTrue(0 != result);
        avm.shutdown();
    }

    /**
     * Tests that the internal call depth limit is in effect; aka, "CallDepthLimitExceededException"
     * is thrown once the limit is reached.
     */
    @Test
    public void testCallDepthLimit() {
        byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(ReentrantCrossCallResource.clreplaced);
        byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        TestingState kernel = new TestingState(block);
        AvmImpl avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
        // deploy
        AionAddress contractAddr = createDApp(kernel, avm, txData);
        // Verify the internal call depth limit is in effect.
        byte[] callData = encodeCallIntInt("recursiveChangeNested", 0, 10);
        Transaction tx = AvmTransactionUtil.call(deployer, contractAddr, kernel.getNonce(deployer), BigInteger.ZERO, callData, 20_000_000l, 1L);
        TransactionResult result2 = avm.run(kernel, new Transaction[] { tx }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
        replacedertEquals(AvmInternalError.FAILED_EXCEPTION.error, result2.transactionStatus.causeOfError);
        avm.shutdown();
    }

    /**
     * Tests that a DApp can CREATE and then CALL another instance.
     */
    @Test
    public void testCreateAndCallSubApp() {
        byte incrementBy = 2;
        byte[] incrementorJar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(IncrementorDApp.clreplaced);
        byte[] incrementorCreateData = new CodeAndArguments(incrementorJar, new byte[] { incrementBy }).encodeToBytes();
        byte[] spawnerJar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(SpawnerDApp.clreplaced);
        byte[] spanerCreateData = new CodeAndArguments(spawnerJar, incrementorCreateData).encodeToBytes();
        TestingState kernel = new TestingState(block);
        AvmImpl avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
        // CREATE the spawner.
        AionAddress spawnerAddress = createDApp(kernel, avm, spanerCreateData);
        // CALL to create and invoke the incrementor.
        byte[] input = new byte[] { 1, 2, 3, 4, 5 };
        byte[] incrementorCallData = encodeCallByteArray("incrementArray", input);
        byte[] spawnerCallData = encodeCallByteArray("spawnAndCall", incrementorCallData);
        byte[] incrementorResult = callDAppByteArray(kernel, avm, spawnerAddress, spawnerCallData);
        // We double-encoded the arguments, so double-decode the response.
        byte[] spawnerResult = new ABIDecoder(incrementorResult).decodeOneByteArray();
        replacedertEquals(input.length, spawnerResult.length);
        for (int i = 0; i < input.length; ++i) {
            replacedertEquals(incrementBy + input[i], spawnerResult[i]);
        }
        avm.shutdown();
    }

    /**
     * Tests that a DApp can CREATE for us.
     */
    @Test
    public void testCreateSubAppCall() {
        byte incrementBy = 3;
        byte[] incrementorJar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(IncrementorDApp.clreplaced);
        byte[] incrementorCreateData = new CodeAndArguments(incrementorJar, new byte[] { incrementBy }).encodeToBytes();
        byte[] spawnerJar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(SpawnerDApp.clreplaced);
        byte[] spanerCreateData = new CodeAndArguments(spawnerJar, incrementorCreateData).encodeToBytes();
        TestingState kernel = new TestingState(block);
        AvmImpl avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
        // CREATE the spawner.
        AionAddress spawnerAddress = createDApp(kernel, avm, spanerCreateData);
        // CALL to create and invoke the incrementor.
        boolean shouldFail = false;
        byte[] spawnerCallData = encodeCallBool("spawnOnly", shouldFail);
        Address incrementorAddress = callDAppAddress(kernel, avm, spawnerAddress, spawnerCallData);
        // Call the incrementor, directly.
        byte[] input = new byte[] { 1, 2, 3, 4, 5 };
        byte[] incrementorCallData = encodeCallByteArray("incrementArray", input);
        byte[] incrementorResult = callDAppByteArray(kernel, avm, new AionAddress(incrementorAddress.toByteArray()), incrementorCallData);
        replacedertEquals(input.length, incrementorResult.length);
        for (int i = 0; i < input.length; ++i) {
            replacedertEquals(incrementBy + input[i], incrementorResult[i]);
        }
        avm.shutdown();
    }

    /**
     * Tests that a DApp can CREATE for us (but is reverted on failure).
     */
    @Test
    public void testCreateSubAppCallFailure() {
        byte incrementBy = 3;
        byte[] incrementorJar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(IncrementorDApp.clreplaced);
        byte[] incrementorCreateData = new CodeAndArguments(incrementorJar, new byte[] { incrementBy }).encodeToBytes();
        byte[] spawnerJar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(SpawnerDApp.clreplaced);
        byte[] spanerCreateData = new CodeAndArguments(spawnerJar, incrementorCreateData).encodeToBytes();
        TestingState kernel = new TestingState(block);
        AvmImpl avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
        // CREATE the spawner.
        AionAddress spawnerAddress = createDApp(kernel, avm, spanerCreateData);
        // CALL to create and invoke the incrementor.
        boolean shouldFail = true;
        byte[] spawnerCallData = encodeCallBool("spawnOnly", shouldFail);
        long energyLimit = 1_000_000l;
        Transaction tx = AvmTransactionUtil.call(TestingState.PREMINED_ADDRESS, spawnerAddress, kernel.getNonce(deployer), BigInteger.ZERO, spawnerCallData, energyLimit, 1L);
        TransactionResult result2 = avm.run(kernel, new Transaction[] { tx }, ExecutionType.replacedUME_MAINCHAIN, kernel.getBlockNumber() - 1)[0].getResult();
        replacedertEquals(AvmInternalError.FAILED_INVALID.error, result2.transactionStatus.causeOfError);
        avm.shutdown();
    }

    /**
     * Tests that a DApp can CREATE for us, backed by a directory.
     * (same as "testCreateSubAppCall" but uses a directory backing-store).
     */
    @Test
    public void testCreateSubAppCallOnDirectory() throws Exception {
        File directory = folder.newFolder();
        byte incrementBy = 3;
        byte[] incrementorJar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(IncrementorDApp.clreplaced);
        byte[] incrementorCreateData = new CodeAndArguments(incrementorJar, new byte[] { incrementBy }).encodeToBytes();
        byte[] spawnerJar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(SpawnerDApp.clreplaced);
        byte[] spanerCreateData = new CodeAndArguments(spawnerJar, incrementorCreateData).encodeToBytes();
        TestingState kernel = new TestingState(directory, block);
        AvmImpl avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
        // We always start out with the PREMINE account, but that should be the only one.
        replacedertEquals(1, directory.listFiles().length);
        // CREATE the spawner (meaning another account). Expect 3 accounts because: deployer, contract, coinbase
        AionAddress spawnerAddress = createDApp(kernel, avm, spanerCreateData);
        replacedertEquals(3, directory.listFiles().length);
        // CALL to create and invoke the incrementor. Expect 4 accounts because: deployer, contract1, contract2, coinbase
        boolean shouldFail = false;
        byte[] spawnerCallData = encodeCallBool("spawnOnly", shouldFail);
        Address incrementorAddress = callDAppAddress(kernel, avm, spawnerAddress, spawnerCallData);
        replacedertEquals(4, directory.listFiles().length);
        // Restart the AVM.
        avm.shutdown();
        kernel = new TestingState(directory, block);
        avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
        // Call the incrementor, directly.
        byte[] input = new byte[] { 1, 2, 3, 4, 5 };
        byte[] incrementorCallData = encodeCallByteArray("incrementArray", input);
        byte[] incrementorResult = callDAppByteArray(kernel, avm, new AionAddress(incrementorAddress.toByteArray()), incrementorCallData);
        replacedertEquals(input.length, incrementorResult.length);
        for (int i = 0; i < input.length; ++i) {
            replacedertEquals(incrementBy + input[i], incrementorResult[i]);
        }
        // Check the state of the directory we are using to back this (4 accounts, 2 with code and 2 with only a balance).
        int codeCount = 0;
        int balanceCount = 0;
        for (File top : directory.listFiles()) {
            for (File account : top.listFiles()) {
                if ("code".equals(account.getName())) {
                    codeCount += 1;
                } else if ("balance".equals(account.getName())) {
                    balanceCount += 1;
                }
            }
        }
        replacedertEquals(2, codeCount);
        replacedertEquals(4, balanceCount);
        avm.shutdown();
    }

    @Test
    public void testDeployFailedWithNullMainClreplaced() {
        byte[] jar = JarBuilder.buildJarForMainClreplacedAndExplicitClreplacedNamesAndBytecode(null, Collections.emptyMap(), MainClreplaced.clreplaced);
        deployInvalidJar(jar);
    }

    @Test
    public void testDeployFailedWithMissingMainClreplaced() {
        byte[] jar = JarBuilder.buildJarForExplicitMainAndClreplacedes("NonExistentClreplaced", MainClreplaced.clreplaced);
        deployInvalidJar(jar);
    }

    @Test
    public void testDeployFailedWithInvalidMainClreplaced() {
        byte[] jar = JarBuilder.buildJarForExplicitMainAndClreplacedes(".Invalid..Clreplaced.....Name", MainClreplaced.clreplaced);
        deployInvalidJar(jar);
    }

    @Test
    public void testDeployFailedWithMissingMainMethod() {
        byte[] jar = JarBuilder.buildJarForMainClreplacedAndExplicitClreplacedNamesAndBytecode(InterfaceTestResource.clreplaced, Collections.emptyMap(), MainClreplaced.clreplaced);
        deployInvalidJar(jar);
    }

    @Test
    public void testDeployFailedWithInvalidMainClreplacedBytecode() {
        byte[] jar = JarBuilder.buildJarForExplicitClreplacedNamesAndBytecode("NotAValidClreplaced", new byte[] { 0x1, 0x2, 0x3 }, Collections.emptyMap());
        deployInvalidJar(jar);
    }

    /**
     * Tests that a DApp can CREATE from within its own CREATE, so long as we only go 10 levels down (the limit).
     */
    @Test
    public void testCreateInClinit_success() {
        byte[] spawnerCreateData = buildRecursiveCreate(10);
        TestingState kernel = new TestingState(block);
        AvmImpl avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
        TransactionResult createResult = createDAppCanFail(kernel, avm, spawnerCreateData);
        replacedertTrue(createResult.transactionStatus.isSuccess());
        AionAddress spawnerAddress = new AionAddress(createResult.copyOfTransactionOutput().orElseThrow());
        replacedertNotNull(spawnerAddress);
        avm.shutdown();
    }

    /**
     * Tests that a DApp can CREATE from within its own CREATE, and fails after 11 levels down (since 10 is the limit).
     */
    @Test
    public void testCreateInClinit_failure() {
        byte[] spawnerCreateData = buildRecursiveCreate(11);
        TestingState kernel = new TestingState(block);
        AvmImpl avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
        TransactionResult createResult = createDAppCanFail(kernel, avm, spawnerCreateData);
        // We are ultimately failing due to the replacedertionError the clreplaced triggers if the create fails.
        replacedertEquals(AvmInternalError.FAILED_EXCEPTION.error, createResult.transactionStatus.causeOfError);
        avm.shutdown();
    }

    private int callRecursiveHash(IExternalState externalState, AvmImpl avm, long energyLimit, AionAddress contractAddr, int depth) {
        byte[] argData = encodeCallInt("getRecursiveHashCode", depth);
        Transaction call = AvmTransactionUtil.call(deployer, contractAddr, externalState.getNonce(deployer), BigInteger.ZERO, argData, energyLimit, 1L);
        TransactionResult result = avm.run(externalState, new Transaction[] { call }, ExecutionType.replacedUME_MAINCHAIN, externalState.getBlockNumber() - 1)[0].getResult();
        replacedertTrue(result.transactionStatus.isSuccess());
        return new ABIDecoder(result.copyOfTransactionOutput().orElseThrow()).decodeOneInteger();
    }

    private int callReentrantAccess(IExternalState externalState, AvmImpl avm, AionAddress contractAddr, String methodName, boolean shouldFail) {
        byte[] nearData = encodeCallBool(methodName, shouldFail);
        return callDAppInteger(externalState, avm, contractAddr, nearData);
    }

    private AionAddress createDApp(IExternalState externalState, AvmImpl avm, byte[] createData) {
        TransactionResult result1 = createDAppCanFail(externalState, avm, createData);
        replacedertTrue(result1.transactionStatus.isSuccess());
        return new AionAddress(result1.copyOfTransactionOutput().orElseThrow());
    }

    private TransactionResult createDAppCanFail(IExternalState externalState, AvmImpl avm, byte[] createData) {
        long energyLimit = 10_000_000l;
        long energyPrice = 1l;
        Transaction tx1 = AvmTransactionUtil.create(deployer, externalState.getNonce(deployer), BigInteger.ZERO, createData, energyLimit, energyPrice);
        return avm.run(externalState, new Transaction[] { tx1 }, ExecutionType.replacedUME_MAINCHAIN, externalState.getBlockNumber() - 1)[0].getResult();
    }

    private void callDAppVoid(IExternalState externalState, AvmImpl avm, AionAddress dAppAddress, byte[] argData) {
        byte[] result = callDAppSuccess(externalState, avm, dAppAddress, argData);
        replacedertArrayEquals(new byte[0], result);
    }

    private boolean callDAppBoolean(IExternalState externalState, AvmImpl avm, AionAddress dAppAddress, byte[] argData) {
        byte[] result = callDAppSuccess(externalState, avm, dAppAddress, argData);
        return new ABIDecoder(result).decodeOneBoolean();
    }

    private int callDAppInteger(IExternalState externalState, AvmImpl avm, AionAddress dAppAddress, byte[] argData) {
        byte[] result = callDAppSuccess(externalState, avm, dAppAddress, argData);
        return new ABIDecoder(result).decodeOneInteger();
    }

    private byte[] callDAppByteArray(IExternalState externalState, AvmImpl avm, AionAddress dAppAddress, byte[] argData) {
        byte[] result = callDAppSuccess(externalState, avm, dAppAddress, argData);
        return new ABIDecoder(result).decodeOneByteArray();
    }

    private Address callDAppAddress(IExternalState externalState, AvmImpl avm, AionAddress dAppAddress, byte[] argData) {
        byte[] result = callDAppSuccess(externalState, avm, dAppAddress, argData);
        return new ABIDecoder(result).decodeOneAddress();
    }

    private byte[] callDAppSuccess(IExternalState externalState, AvmImpl avm, AionAddress dAppAddress, byte[] argData) {
        long energyLimit = 5_000_000l;
        Transaction tx = AvmTransactionUtil.call(deployer, dAppAddress, externalState.getNonce(deployer), BigInteger.ZERO, argData, energyLimit, 1L);
        TransactionResult result2 = avm.run(externalState, new Transaction[] { tx }, ExecutionType.replacedUME_MAINCHAIN, externalState.getBlockNumber() - 1)[0].getResult();
        replacedertTrue(result2.transactionStatus.isSuccess());
        return result2.copyOfTransactionOutput().orElseThrow();
    }

    private void deployInvalidJar(byte[] jar) {
        byte[] deployment = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
        TestingState kernel = new TestingState(block);
        AvmImpl avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
        long energyLimit = 10_000_000l;
        long energyPrice = 1l;
        Transaction tx1 = AvmTransactionUtil.create(deployer, kernel.getNonce(deployer), BigInteger.ZERO, deployment, energyLimit, energyPrice);
        TransactionResult result1 = avm.run(kernel, new Transaction[] { tx1 }, ExecutionType.replacedUME_MAINCHAIN, 0)[0].getResult();
        avm.shutdown();
        replacedertEquals(AvmInternalError.FAILED_INVALID_DATA.error, result1.transactionStatus.causeOfError);
    }

    private byte[] buildRecursiveCreate(int levelsToAdd) {
        byte[] args = (levelsToAdd > 1) ? buildRecursiveCreate(levelsToAdd - 1) : new byte[0];
        byte[] recursiveSpawner = JarBuilder.buildJarForMainClreplacedAndExplicitClreplacedNamesAndBytecode(RecursiveSpawnerResource.clreplaced, Collections.emptyMap());
        return new CodeAndArguments(recursiveSpawner, args).encodeToBytes();
    }

    private static byte[] encodeNoArgCall(String methodName) {
        return new ABIStreamingEncoder().encodeOneString(methodName).toBytes();
    }

    private static byte[] encodeCallBool(String methodName, boolean arg) {
        return new ABIStreamingEncoder().encodeOneString(methodName).encodeOneBoolean(arg).toBytes();
    }

    private static byte[] encodeCallByteArray(String methodName, byte[] arg) {
        return new ABIStreamingEncoder().encodeOneString(methodName).encodeOneByteArray(arg).toBytes();
    }

    private static byte[] encodeCallLong(String methodName, long arg) {
        return new ABIStreamingEncoder().encodeOneString(methodName).encodeOneLong(arg).toBytes();
    }

    private static byte[] encodeCallInt(String methodName, int arg) {
        return new ABIStreamingEncoder().encodeOneString(methodName).encodeOneInteger(arg).toBytes();
    }

    private static byte[] encodeCallIntInt(String methodName, int arg1, int arg2) {
        return new ABIStreamingEncoder().encodeOneString(methodName).encodeOneInteger(arg1).encodeOneInteger(arg2).toBytes();
    }
}

19 Source : AvmImplTest.java
with MIT License
from aionnetwork

/**
 * Tests that a DApp can CREATE for us, backed by a directory.
 * (same as "testCreateSubAppCall" but uses a directory backing-store).
 */
@Test
public void testCreateSubAppCallOnDirectory() throws Exception {
    File directory = folder.newFolder();
    byte incrementBy = 3;
    byte[] incrementorJar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(IncrementorDApp.clreplaced);
    byte[] incrementorCreateData = new CodeAndArguments(incrementorJar, new byte[] { incrementBy }).encodeToBytes();
    byte[] spawnerJar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(SpawnerDApp.clreplaced);
    byte[] spanerCreateData = new CodeAndArguments(spawnerJar, incrementorCreateData).encodeToBytes();
    TestingState kernel = new TestingState(directory, block);
    AvmImpl avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
    // We always start out with the PREMINE account, but that should be the only one.
    replacedertEquals(1, directory.listFiles().length);
    // CREATE the spawner (meaning another account). Expect 3 accounts because: deployer, contract, coinbase
    AionAddress spawnerAddress = createDApp(kernel, avm, spanerCreateData);
    replacedertEquals(3, directory.listFiles().length);
    // CALL to create and invoke the incrementor. Expect 4 accounts because: deployer, contract1, contract2, coinbase
    boolean shouldFail = false;
    byte[] spawnerCallData = encodeCallBool("spawnOnly", shouldFail);
    Address incrementorAddress = callDAppAddress(kernel, avm, spawnerAddress, spawnerCallData);
    replacedertEquals(4, directory.listFiles().length);
    // Restart the AVM.
    avm.shutdown();
    kernel = new TestingState(directory, block);
    avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
    // Call the incrementor, directly.
    byte[] input = new byte[] { 1, 2, 3, 4, 5 };
    byte[] incrementorCallData = encodeCallByteArray("incrementArray", input);
    byte[] incrementorResult = callDAppByteArray(kernel, avm, new AionAddress(incrementorAddress.toByteArray()), incrementorCallData);
    replacedertEquals(input.length, incrementorResult.length);
    for (int i = 0; i < input.length; ++i) {
        replacedertEquals(incrementBy + input[i], incrementorResult[i]);
    }
    // Check the state of the directory we are using to back this (4 accounts, 2 with code and 2 with only a balance).
    int codeCount = 0;
    int balanceCount = 0;
    for (File top : directory.listFiles()) {
        for (File account : top.listFiles()) {
            if ("code".equals(account.getName())) {
                codeCount += 1;
            } else if ("balance".equals(account.getName())) {
                balanceCount += 1;
            }
        }
    }
    replacedertEquals(2, codeCount);
    replacedertEquals(4, balanceCount);
    avm.shutdown();
}

19 Source : AvmImplTest.java
with MIT License
from aionnetwork

/**
 * Tests that reentrant calls do have detectable side-effects within the caller's space, when they commit.
 */
@Test
public void testCommitReentrantCalls() {
    boolean shouldFail = false;
    byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(ReentrantCrossCallResource.clreplaced);
    byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
    TestingState kernel = new TestingState(block);
    AvmImpl avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
    // deploy
    AionAddress contractAddr = createDApp(kernel, avm, txData);
    // Get direct increments from 1 to 2 and returns 2.
    replacedertEquals(2, callReentrantAccess(kernel, avm, contractAddr, "getDirect", shouldFail));
    // Get near increments from 1 to 2 and returns 2.
    replacedertEquals(2, callReentrantAccess(kernel, avm, contractAddr, "getNear", shouldFail));
    // Get far increments from 1 to 2 and returns 2.
    replacedertEquals(2, callReentrantAccess(kernel, avm, contractAddr, "getFar", shouldFail));
    // Get near increments from 2 to 3 and returns 3.
    replacedertEquals(3, callReentrantAccess(kernel, avm, contractAddr, "getNear", shouldFail));
    avm.shutdown();
}

19 Source : AvmImplTest.java
with MIT License
from aionnetwork

@Test
public void testRecursiveHashCode() {
    byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(ReentrantCrossCallResource.clreplaced);
    byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
    TestingState kernel = new TestingState(block);
    AvmImpl avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
    // deploy
    long energyLimit = 10_000_000l;
    AionAddress contractAddr = createDApp(kernel, avm, txData);
    // Try a few invocations of different depths, bearing in mind the change of nextHashCode between each invocation.
    // We will do 2 zero-depth calls to see the delta between the 2 calls.
    // Then, we will do an indirect call and verify that the delta is greater.
    // If the hashcode wasn't restored across reentrant calls, this wouldn't be greater as it wouldn't capture the small cost of the original
    // indirect call (since we create at least 1 object in that path).
    int zero0 = callRecursiveHash(kernel, avm, energyLimit, contractAddr, 0);
    int zero1 = callRecursiveHash(kernel, avm, energyLimit, contractAddr, 0);
    int zero2 = callRecursiveHash(kernel, avm, energyLimit, contractAddr, 0);
    int one0 = callRecursiveHash(kernel, avm, energyLimit, contractAddr, 1);
    int one1 = callRecursiveHash(kernel, avm, energyLimit, contractAddr, 1);
    int one2 = callRecursiveHash(kernel, avm, energyLimit, contractAddr, 1);
    replacedertEquals(zero1 - zero0, zero2 - zero1);
    replacedertEquals(one1 - one0, one2 - one1);
    replacedertTrue((one1 - one0) > (zero1 - zero0));
    avm.shutdown();
}

19 Source : AvmImplTest.java
with MIT License
from aionnetwork

private byte[] callDAppByteArray(IExternalState externalState, AvmImpl avm, AionAddress dAppAddress, byte[] argData) {
    byte[] result = callDAppSuccess(externalState, avm, dAppAddress, argData);
    return new ABIDecoder(result).decodeOneByteArray();
}

19 Source : AvmImplTest.java
with MIT License
from aionnetwork

/**
 * Tests that a DApp can CREATE for us.
 */
@Test
public void testCreateSubAppCall() {
    byte incrementBy = 3;
    byte[] incrementorJar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(IncrementorDApp.clreplaced);
    byte[] incrementorCreateData = new CodeAndArguments(incrementorJar, new byte[] { incrementBy }).encodeToBytes();
    byte[] spawnerJar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(SpawnerDApp.clreplaced);
    byte[] spanerCreateData = new CodeAndArguments(spawnerJar, incrementorCreateData).encodeToBytes();
    TestingState kernel = new TestingState(block);
    AvmImpl avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
    // CREATE the spawner.
    AionAddress spawnerAddress = createDApp(kernel, avm, spanerCreateData);
    // CALL to create and invoke the incrementor.
    boolean shouldFail = false;
    byte[] spawnerCallData = encodeCallBool("spawnOnly", shouldFail);
    Address incrementorAddress = callDAppAddress(kernel, avm, spawnerAddress, spawnerCallData);
    // Call the incrementor, directly.
    byte[] input = new byte[] { 1, 2, 3, 4, 5 };
    byte[] incrementorCallData = encodeCallByteArray("incrementArray", input);
    byte[] incrementorResult = callDAppByteArray(kernel, avm, new AionAddress(incrementorAddress.toByteArray()), incrementorCallData);
    replacedertEquals(input.length, incrementorResult.length);
    for (int i = 0; i < input.length; ++i) {
        replacedertEquals(incrementBy + input[i], incrementorResult[i]);
    }
    avm.shutdown();
}

19 Source : AvmImplTest.java
with MIT License
from aionnetwork

private Address callDAppAddress(IExternalState externalState, AvmImpl avm, AionAddress dAppAddress, byte[] argData) {
    byte[] result = callDAppSuccess(externalState, avm, dAppAddress, argData);
    return new ABIDecoder(result).decodeOneAddress();
}

19 Source : AvmImplTest.java
with MIT License
from aionnetwork

/**
 * Tests that reentrant calls do NOT have detectable side-effects within the caller's space, when they rollback.
 */
@Test
public void testRollbackReentrantCalls() {
    boolean shouldFail = true;
    byte[] jar = UserlibJarBuilder.buildJarForMainAndClreplacedesAndUserlib(ReentrantCrossCallResource.clreplaced);
    byte[] txData = new CodeAndArguments(jar, new byte[0]).encodeToBytes();
    TestingState kernel = new TestingState(block);
    AvmImpl avm = CommonAvmFactory.buildAvmInstanceForConfiguration(new EmptyCapabilities(), new AvmConfiguration());
    // deploy
    AionAddress contractAddr = createDApp(kernel, avm, txData);
    // We expect these to all fail, so they should be left with the initial values:  1.
    replacedertEquals(1, callReentrantAccess(kernel, avm, contractAddr, "getDirect", shouldFail));
    replacedertEquals(1, callReentrantAccess(kernel, avm, contractAddr, "getNear", shouldFail));
    replacedertEquals(1, callReentrantAccess(kernel, avm, contractAddr, "getFar", shouldFail));
    replacedertEquals(1, callReentrantAccess(kernel, avm, contractAddr, "getNear", shouldFail));
    avm.shutdown();
}

See More Examples