Search in sources :

Example 16 with StandaloneBlockchain

use of org.aion.zero.impl.blockchain.StandaloneBlockchain in project aion by aionnetwork.

the class DetailsDataStoreIntegTest method largeStorageTransitionBenchmark.

/**
 * Creates a contract with large storage. Imports 20 blocks expanding the storage and prints
 * times and database size with and without storage transition.
 */
@Ignore
@Test
public void largeStorageTransitionBenchmark() throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException {
    // setup account used to deploy and call the large storage contract
    List<ECKey> accounts = generateAccounts(1);
    ECKey account = accounts.get(0);
    // setup AVM
    // clear setting from @Before
    AvmTestConfig.clearConfigurations();
    TransactionTypeRule.allowAVMContractTransaction();
    resourceProvider = TestResourceProvider.initializeAndCreateNewProvider(AvmPathManager.getPathOfProjectRootDirectory());
    // enable both AVMs without overlap
    AvmTestConfig.supportBothAvmVersions(0, 1, 0);
    // setup 3 identical blockchains
    StandaloneBlockchain.Builder builder = new StandaloneBlockchain.Builder();
    StandaloneBlockchain chain = builder.withValidatorConfiguration("simple").withDefaultAccounts(accounts).withAvmEnabled().build().bc;
    StandaloneBlockchain chainWithTransition = builder.withValidatorConfiguration("simple").withDefaultAccounts(accounts).withAvmEnabled().build().bc;
    StandaloneBlockchain chainWithoutTransition = builder.withValidatorConfiguration("simple").withDefaultAccounts(accounts).withAvmEnabled().build().bc;
    // disabling Unity for this test
    chain.forkUtility.disableUnityFork();
    chainWithTransition.forkUtility.disableUnityFork();
    chainWithoutTransition.forkUtility.disableUnityFork();
    assertThat(chain).isNotEqualTo(chainWithTransition);
    assertThat(chain.genesis).isEqualTo(chainWithTransition.genesis);
    assertThat(chain).isNotEqualTo(chainWithoutTransition);
    assertThat(chain.genesis).isEqualTo(chainWithoutTransition.genesis);
    assertThat(chainWithoutTransition).isNotEqualTo(chainWithTransition);
    assertThat(chainWithoutTransition.genesis).isEqualTo(chainWithTransition.genesis);
    // deploy the storage contract
    BigInteger nonce = BigInteger.ZERO;
    AionTransaction tx = deployAvmContractTransaction(AvmContract.LARGE_STORAGE, resourceProvider.factoryForVersion2, account, nonce);
    nonce = nonce.add(BigInteger.ONE);
    addMiningBlock(chain, chain.getBestBlock(), List.of(tx));
    // save the contract address
    AionAddress contract = TxUtil.calculateContractAddress(tx);
    System.out.println("Contract: " + contract);
    List<AionTransaction> txs = new ArrayList<>();
    int insertTxPerBlock = 9, updateTxPerBlock = 5, deleteTxPerBlock = 4;
    // results in 3*6 blocks with storage in details, 3*6 after transition
    int numberOfStorageBlocks = 2 * 6;
    LinkedList<byte[]> keys = new LinkedList<>();
    // populate chain
    for (int i = 0; i < numberOfStorageBlocks; i++) {
        // call contract to increase storage
        for (int j = 0; j < insertTxPerBlock; j++) {
            byte[] key = RandomUtils.nextBytes(32 - i);
            txs.add(putToLargeStorageTransaction(resourceProvider.factoryForVersion2, account, key, RandomUtils.nextBytes(32 - i), nonce, contract));
            nonce = nonce.add(BigInteger.ONE);
            keys.addLast(key);
        }
        addMiningBlock(chain, chain.getBestBlock(), txs);
        // call contract to update storage
        for (int j = 0; j < updateTxPerBlock; j++) {
            byte[] key = keys.removeFirst();
            txs.add(putToLargeStorageTransaction(resourceProvider.factoryForVersion2, account, key, RandomUtils.nextBytes(32 - i - 1), nonce, contract));
            nonce = nonce.add(BigInteger.ONE);
            keys.addLast(key);
        }
        addMiningBlock(chain, chain.getBestBlock(), txs);
        // call contract to delete storage
        for (int j = 0; j < deleteTxPerBlock; j++) {
            txs.add(putToLargeStorageTransaction(resourceProvider.factoryForVersion2, account, keys.removeFirst(), null, nonce, contract));
            nonce = nonce.add(BigInteger.ONE);
        }
        addMiningBlock(chain, chain.getBestBlock(), txs);
    }
    // import the contract block (not part of the benchmark)
    Block block = chain.getBlockByNumber(1);
    ImportResult importResult = chainWithoutTransition.tryToConnect(block);
    assertThat(importResult).isEqualTo(ImportResult.IMPORTED_BEST);
    importResult = chainWithTransition.tryToConnect(block);
    assertThat(importResult).isEqualTo(ImportResult.IMPORTED_BEST);
    long start, duration, storage, details, size;
    long totalTimeWithTransition = 0, totalDetailsSizeWithTransition = 0, totalStorageSizeWithTransition = 0, totalSizeWithTransition = 0, totalTimeWithoutTransition = 0, totalDetailsSizeWithoutTransition = 0, totalStorageSizeWithoutTransition = 0, totalSizeWithoutTransition = 0;
    int blocks = (int) chain.getBestBlock().getNumber();
    long[][] results = new long[blocks + 1][8];
    boolean isEmptyStorage = true, isSaved = false;
    // generate data by importing each block to the chain with/without transition
    for (int i = 2; i <= blocks; i++) {
        block = chain.getBlockByNumber(i);
        // importing without transition first
        // In case there is any bias due to caching, it will disfavour this option.
        // Even with any potential nevative bias, the option seems to have better performance.
        // AionContractDetailsImpl.detailsInMemoryStorageLimit = 0;
        start = System.nanoTime();
        importResult = chainWithoutTransition.tryToConnect(block);
        duration = System.nanoTime() - start;
        assertThat(importResult).isEqualTo(ImportResult.IMPORTED_BEST);
        details = chainWithoutTransition.getRepository().detailsDatabase.approximateSize();
        storage = chainWithoutTransition.getRepository().storageDatabase.approximateSize();
        size = details + storage;
        results[i][4] = duration;
        results[i][5] = details;
        results[i][6] = storage;
        results[i][7] = size;
        totalTimeWithoutTransition += duration;
        totalDetailsSizeWithoutTransition += details;
        totalStorageSizeWithoutTransition += storage;
        totalSizeWithoutTransition += size;
        if (storage != 0 && isEmptyStorage) {
            isEmptyStorage = false;
        }
        if (!isEmptyStorage && !isSaved) {
            results[1][0] = totalTimeWithTransition;
            results[1][1] = totalDetailsSizeWithTransition;
            results[1][2] = totalStorageSizeWithTransition;
            results[1][3] = totalSizeWithTransition;
            results[1][4] = totalTimeWithoutTransition;
            results[1][5] = totalDetailsSizeWithoutTransition;
            results[1][6] = totalStorageSizeWithoutTransition;
            results[1][7] = totalSizeWithoutTransition;
            isSaved = true;
        }
    }
    // Save totals
    results[0][0] = totalTimeWithTransition;
    results[0][1] = totalDetailsSizeWithTransition;
    results[0][2] = totalStorageSizeWithTransition;
    results[0][3] = totalSizeWithTransition;
    results[0][4] = totalTimeWithoutTransition;
    results[0][5] = totalDetailsSizeWithoutTransition;
    results[0][6] = totalStorageSizeWithoutTransition;
    results[0][7] = totalSizeWithoutTransition;
    print(results);
}
Also used : AionAddress(org.aion.types.AionAddress) ImportResult(org.aion.zero.impl.core.ImportResult) ArrayList(java.util.ArrayList) ECKey(org.aion.crypto.ECKey) StandaloneBlockchain(org.aion.zero.impl.blockchain.StandaloneBlockchain) AionTransaction(org.aion.base.AionTransaction) LinkedList(java.util.LinkedList) BigInteger(java.math.BigInteger) Block(org.aion.zero.impl.types.Block) BlockchainTestUtils.addStakingBlock(org.aion.zero.impl.blockchain.BlockchainTestUtils.addStakingBlock) BlockchainTestUtils.addMiningBlock(org.aion.zero.impl.blockchain.BlockchainTestUtils.addMiningBlock) Ignore(org.junit.Ignore) Test(org.junit.Test)

Example 17 with StandaloneBlockchain

use of org.aion.zero.impl.blockchain.StandaloneBlockchain in project aion by aionnetwork.

the class FvmExploitsTest method testAddInvalidAndThenValidBlocks.

@Test
public void testAddInvalidAndThenValidBlocks() throws InterruptedException {
    String testerByteCode = "0x60506040525b3360006000508282909180600101839055555050505b610020565b6107ab8061002f6000396000f30060506040523615610096576000356c01000000000000000000000000900463ffffffff16806306c8dcde1461009a578063590e1ae3146100c657806367a3914e146100dc5780636aee4cac1461010857806379ba5097146101525780638135ceea146101685780638da5cb5b146101d9578063a6f9dae11461020a578063b22fce4014610236578063d4ee1d901461027a57610096565b5b5b005b34156100a65760006000fd5b6100c4600480808060100135903590916020019091929050506102ab565b005b34156100d25760006000fd5b6100da610308565b005b34156100e85760006000fd5b6101066004808080601001359035909160200190919290505061035a565b005b34156101145760006000fd5b610138600480808060100135903590600019169090916020019091929050506103b7565b604051808215151515815260100191505060405180910390f35b341561015e5760006000fd5b6101666103e3565b005b34156101745760006000fd5b6101d760048080806010013590359060001916909091602001909192908080601001359035906000191690909160200190919290803590601001908201803590601001919091929080359060100190820180359060100191909192905050610470565b005b34156101e55760006000fd5b6101ed61062b565b604051808383825281601001526020019250505060405180910390f35b34156102165760006000fd5b6102346004808080601001359035909160200190919290505061063a565b005b34156102425760006000fd5b61026060048080806010013590359091602001909192905050610676565b604051808215151515815260100191505060405180910390f35b34156102865760006000fd5b61028e6106a2565b604051808383825281601001526020019250505060405180910390f35b600060005080600101549054339091149190141615156102cb5760006000fd5b600160046000506000848482528160100152602001908152601001600020905060006101000a81548160ff0219169083151502179055505b5b5050565b600060005080600101549054339091149190141615156103285760006000fd5b336108fc3031908115029060405160006040518083038185898989f194505050505015156103565760006000fd5b5b5b565b6000600050806001015490543390911491901416151561037a5760006000fd5b600060046000506000848482528160100152602001908152601001600020905060006101000a81548160ff0219169083151502179055505b5b5050565b60056000506020528181600052601052603060002090506000915091509054906101000a900460ff1681565b60026000508060010154905433909114919014161561046d5760026000508060010154905460006000508282909180600101839055555050506000600060026000508282909180600101839055555050506000600050806001015490547fa701229f4b9ddf00aa1c7228d248e6320ee7c581d856ddfba036e73947cd0d1360405160405180910390a25b5b565b60006000600050806001015490543390911491901416806104b85750600460005060003382528160100152602001908152601001600020905060009054906101000a900460ff165b15156104c45760006000fd5b868660056000506000838390600019169090600019169082528160100152602001908152601001600020905060009054906101000a900460ff1615151561050b5760006000fd5b600092506000925082505b8686905083101561057157610563878785818110151561053257fe5b905090906020020180601001359035878787818110151561054f57fe5b9050909060100201356106b163ffffffff16565b5b8280600101935050610516565b6001600560005060008b8b90600019169090600019169082528160100152602001908152601001600020905060006101000a81548160ff0219169083151502179055507f1fa305c7f8521af161de570532762ed7a60199cde79e18e1d259af34595625218c8c8c8c6040518085859060001916909060001916908252816010015260200183839060001916909060001916908252816010015260200194505050505060405180910390a15b5b50505b505050505050505050565b60006000508060010154905482565b6000600050806001015490543390911491901416151561065a5760006000fd5b818160026000508282909180600101839055555050505b5b5050565b60046000506020528181600052601052603060002090506000915091509054906101000a900460ff1681565b60026000508060010154905482565b6000600050806001015490543390911491901416806106f75750600460005060003382528160100152602001908152601001600020905060009054906101000a900460ff165b15156107035760006000fd5b82826108fc83908115029060405160006040518083038185898989f194505050505015156107315760006000fd5b7fdc3b8ebc415c945740a70187f1d472ad2d64a9e7a87047f38023aec56516976b84848460405180848482528160100152602001828152601001935050505060405180910390a15b5b5050505600a165627a7a7230582042b26e68ff40177f10fcfc05c70e102d5d14648a2134ffeec77c7138bf8d27dd0029";
    StandaloneBlockchain.Bundle bundle = (new StandaloneBlockchain.Builder()).withValidatorConfiguration("simple").withDefaultAccounts().build();
    StandaloneBlockchain bc = bundle.bc;
    ECKey deployerAccount = bundle.privateKeys.get(0);
    // =======================================================================
    BigInteger nonce = BigInteger.ZERO;
    AionTransaction tx = AionTransaction.create(deployerAccount, nonce.toByteArray(), null, new byte[0], ByteUtil.hexStringToBytes(testerByteCode), 1_000_000L, energyPrice, TransactionTypes.DEFAULT, null);
    assertThat(tx.isContractCreationTransaction()).isTrue();
    BlockContext context = bc.createNewMiningBlockContext(bc.getBestBlock(), Collections.singletonList(tx), false);
    ImportResult result = bc.tryToConnect(context.block);
    assertThat(result).isEqualTo(ImportResult.IMPORTED_BEST);
    AionAddress contractAddress = TxUtil.calculateContractAddress(tx);
    Thread.sleep(1000L);
    // =======================================================================
    nonce = nonce.add(BigInteger.ONE);
    AionTransaction tx2 = AionTransaction.create(deployerAccount, nonce.toByteArray(), contractAddress, new BigInteger("100000000000000000000").toByteArray(), new byte[0], 1_000_000L, energyPrice, TransactionTypes.DEFAULT, null);
    BlockContext context2 = bc.createNewMiningBlockContext(bc.getBestBlock(), Collections.singletonList(tx2), false);
    MiningBlock block = context2.block;
    byte[] originalReceiptsHash = block.getReceiptsRoot();
    // try importing an invalid block
    MiningBlockHeader newHeader = MiningBlockHeader.Builder.newInstance().withHeader(block.getHeader()).withReceiptTrieRoot(new byte[32]).build();
    block.updateHeader(newHeader);
    ImportResult result2 = bc.tryToConnect(context2.block);
    assertThat(result2).isEqualTo(ImportResult.INVALID_BLOCK);
    // try importing the correct block
    newHeader = MiningBlockHeader.Builder.newInstance().withHeader(block.getHeader()).withReceiptTrieRoot(originalReceiptsHash).build();
    block.updateHeader(newHeader);
    ImportResult result3 = bc.tryToConnect(context2.block);
    assertThat(result3).isEqualTo(ImportResult.IMPORTED_BEST);
}
Also used : ImportResult(org.aion.zero.impl.core.ImportResult) AionAddress(org.aion.types.AionAddress) BlockContext(org.aion.zero.impl.types.BlockContext) StandaloneBlockchain(org.aion.zero.impl.blockchain.StandaloneBlockchain) ECKey(org.aion.crypto.ECKey) AionTransaction(org.aion.base.AionTransaction) MiningBlock(org.aion.zero.impl.types.MiningBlock) MiningBlockHeader(org.aion.zero.impl.types.MiningBlockHeader) BigInteger(java.math.BigInteger) Test(org.junit.Test)

Example 18 with StandaloneBlockchain

use of org.aion.zero.impl.blockchain.StandaloneBlockchain in project aion by aionnetwork.

the class InternalTransactionTest method testNestedCreate.

/*
    pragma solidity ^0.4.0;

    contract B {}

    contract A {
        address b;

        function A() {
            b = new B();
        }
    }
         */
@Test
public void testNestedCreate() throws Exception {
    String contractA = "0x60506040523415600f5760006000fd5b5b60166048565b604051809103906000f0801582151615602f5760006000fd5b60006000508282909180600101839055555050505b6057565b604051605a8061009f83390190565b603a806100656000396000f30060506040526008565b60006000fd00a165627a7a72305820c0eea40d4778b01848164e58898e9e8c8ab068ed5ee36ed6f0582d119ecbbede002960506040523415600f5760006000fd5b6013565b603a8060206000396000f30060506040526008565b60006000fd00a165627a7a723058208c13bc92baf844f8574632dca44c49776516cb6cd537b10ed700bf61392b6ae80029";
    StandaloneBlockchain.Bundle bundle = (new StandaloneBlockchain.Builder()).withValidatorConfiguration("simple").withDefaultAccounts().build();
    StandaloneBlockchain bc = bundle.bc;
    ECKey deployerAccount = bundle.privateKeys.get(0);
    // ======================
    // DEPLOY
    // ======================
    BigInteger nonce = BigInteger.ZERO;
    AionTransaction tx1 = AionTransaction.create(deployerAccount, nonce.toByteArray(), null, new byte[0], ByteUtil.hexStringToBytes(contractA), 1_000_000L, minEnergyPrice, TransactionTypes.DEFAULT, null);
    BlockContext context = bc.createNewMiningBlockContext(bc.getBestBlock(), List.of(tx1), false);
    AionTxExecSummary summary = executeTransaction(bc, context, tx1);
    System.out.println(summary.getReceipt());
    for (InternalTransaction tx : summary.getInternalTransactions()) {
        System.out.println(tx);
    }
}
Also used : BlockContext(org.aion.zero.impl.types.BlockContext) AionTxExecSummary(org.aion.base.AionTxExecSummary) BigInteger(java.math.BigInteger) StandaloneBlockchain(org.aion.zero.impl.blockchain.StandaloneBlockchain) ECKey(org.aion.crypto.ECKey) AionTransaction(org.aion.base.AionTransaction) InternalTransaction(org.aion.types.InternalTransaction) Test(org.junit.Test)

Example 19 with StandaloneBlockchain

use of org.aion.zero.impl.blockchain.StandaloneBlockchain in project aion by aionnetwork.

the class InternalTransactionTest method testRecursiveCall.

/*
    pragma solidity ^0.4.0;

    contract A {
        function f(int n) {
            if (n > 0) {
                this.f(n - 1);
            }
        }
    }
         */
@Test
public void testRecursiveCall() throws Exception {
    String contractA = "0x605060405234156100105760006000fd5b610015565b60e9806100236000396000f30060506040526000356c01000000000000000000000000900463ffffffff168063ec77996414603157602b565b60006000fd5b3415603c5760006000fd5b605060048080359060100190919050506052565b005b600081131560b9573063ec779964600184036040518263ffffffff166c01000000000000000000000000028152600401808281526010019150506000604051808303816000888881813b151560a75760006000fd5b5af1151560b45760006000fd5b505050505b5b505600a165627a7a7230582033f76d593b80b3468bfb0f873882bc00903a790a9b996cb8ca3bac51295994cd0029";
    StandaloneBlockchain.Bundle bundle = (new StandaloneBlockchain.Builder()).withValidatorConfiguration("simple").withDefaultAccounts().build();
    StandaloneBlockchain bc = bundle.bc;
    ECKey deployerAccount = bundle.privateKeys.get(0);
    // ======================
    // DEPLOY
    // ======================
    BigInteger nonce = BigInteger.ZERO;
    AionTransaction tx1 = AionTransaction.create(deployerAccount, nonce.toByteArray(), null, new byte[0], ByteUtil.hexStringToBytes(contractA), 1_000_000L, minEnergyPrice, TransactionTypes.DEFAULT, null);
    BlockContext context = bc.createNewMiningBlockContext(bc.getBestBlock(), List.of(tx1), false);
    ImportResult result = bc.tryToConnect(context.block);
    assertThat(result).isEqualTo(ImportResult.IMPORTED_BEST);
    AionAddress addressA = TxUtil.calculateContractAddress(tx1);
    System.out.println("contract A = " + addressA);
    Thread.sleep(1000);
    // ======================
    // CALL
    // ======================
    nonce = nonce.add(BigInteger.ONE);
    AionTransaction tx2 = AionTransaction.create(deployerAccount, nonce.toByteArray(), addressA, new byte[0], ByteUtil.merge(ByteUtil.hexStringToBytes("0xec779964"), new DataWord(2).getData()), 1_000_000L, minEnergyPrice, TransactionTypes.DEFAULT, null);
    context = bc.createNewMiningBlockContext(bc.getBestBlock(), List.of(tx2), false);
    AionTxExecSummary summary = executeTransaction(bc, context, tx2);
    assertEquals(2, summary.getInternalTransactions().size());
}
Also used : ImportResult(org.aion.zero.impl.core.ImportResult) AionAddress(org.aion.types.AionAddress) BlockContext(org.aion.zero.impl.types.BlockContext) AionTxExecSummary(org.aion.base.AionTxExecSummary) BigInteger(java.math.BigInteger) StandaloneBlockchain(org.aion.zero.impl.blockchain.StandaloneBlockchain) ECKey(org.aion.crypto.ECKey) AionTransaction(org.aion.base.AionTransaction) DataWord(org.aion.util.types.DataWord) Test(org.junit.Test)

Example 20 with StandaloneBlockchain

use of org.aion.zero.impl.blockchain.StandaloneBlockchain in project aion by aionnetwork.

the class MainnetConsensusTest method testImportBlock3277220.

/**
 * Test for importing block <a href="https://mainnet.aion.network/#/block/3277220">3277220</a>.
 */
@Test
public void testImportBlock3277220() {
    // data extracted from the main network
    Block grandparentBlock = BlockUtil.newBlockFromRlp(Hex.decode("f90791f9078d01833201a2a0a18ad0c32c35c8e62d177385991666f239e39d9c0b674bc38760f1c027b439d4a0a00983f07c11ee9160a64dd3ba3dc3d1f88332a2869f25725f56cbd0be32ef7aa0cc9ce51629c01f203251867e211d915d92526b8d03ad4947054494adfbdcf183a045b0cfc220ceec5b7c1c62c4d4193d38e4eba48e8815729ce75f9c0ab0e4c1c0a045b0cfc220ceec5b7c1c62c4d4193d38e4eba48e8815729ce75f9c0ab0e4c1c0b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000090000000000000000000000000008aa6d0a041494f4e000000000000000000000000000000000000000000000000000000008083e4ed7b845ced093ea0f32a00000000000000000000000000000000000000000000000000001af63326b905800090428cfad06f4e16cc773fe6df521226be292d08022663fdc05063d75e2756af3af5936cfa064b087b05231acc53603ec4dbecefa44451ec7961fccf2b937cd3d25f48c797802cf42fbfcf2e80c6fa99f729949faa7f4f093adb4b3671465c9ca2464a4fcad96d758754eed8821988675096f314d85a110b79f98fffc1cf06987e25df09fc14cb06e4bdd6d91001304d9dd2b853345d1f88af224011a76f8240e9a48c4d564ad74e497d8e27f95d3e0ae15fef29369b2e65bdf30d7a2d2f1336d1ad9b849016797ce03574ca346b9c703f92fe6e94879bfcb4bfd9133f40c7999352cfe1ab70753aae7a9a7c5d78bdbb2e564692c4e6c6ca9e30bd59639e577cdcfe6243fda2d40d48403864581ce8f65ffa59596328b227623f6914a911f7d7f0f345021af10fdb2aad38e775991c42ed598814755148f5c899aee4769a438f33ab79a58d08394d6d20196a5ad9b4ca01f919095e6d9e09b10a7163fa5419011bd7c9e120edb02292ce608a21e0825655faa2a90e63029a72493960e827223f6afcfb8b2f98ad8e6612600207d6853905cbad3ddb8930bc6e2baf947d42efc4f1067583fdc9e3c99ede7f6f358685d19f88e9bce59f5807f6b6fac0191ad9f98b2c1c92d247e0f47d2afa6193111e9e1d77515deca39d5f39c6afc09c34b754664c861114a3619221fb00a3b20697743ea53b1abcef3b9262442e571c6bf80dbc6c50987db0a6ede1fa4eaf2e5c30026162d890511aada4127f12336b89ca8ad83f7473c21845ce2d48e41d2d2fb61b1d688cfa959cff9e7a842404df5b60c8b7b380e49c1d618a07ccf2fcb932b757df21ba26e9f112f36aecb1f0497de78a9ea70f4edfa766028b7949591218b5e6a85809decce0737d6f01f7663a19999cff1aa9aac53ee2222175b9c37c83b5687d77c51e4aee8718b3361a3d5eb68e57fa82809be8f13165152b66ce776ba5a73b338b082c413f79cfcb6678f58b4f016d5a6a7040f7464b50420341225b61586c5dfb6d822843228f5d3d8c77778aa53da7f6a73526ad17e7f6fe163e15621c23b049b85e381e07bc7c8736f11dbe17283f623a8869477ed6f0cd438d84b6d5d68a6a877c68c00250bac4741186d94d0d9024d2f29e102a5a8474032b0c50fd7420526bf62763ac18a60cc81f34d6b7aca91c091db95e61361032d9f7691c7b12cfb704f5d7a2ffa14a9589ed842e3501f8ec778e98063d4a7f0c05bd473106228c5e399642a66abf0f697b877077bb1cb27f0d1d27f02bbbf362dc4a9232d450c0ee550abcdd5ff4bb171ca400bb8706811efcedde1fc5fef244b7cf4f60dd7528d372fffbfb01022c6e3f545d5bad6186e81b5c4faf0c16b26cd4e49f3d677df43a6b7ed5e95fd249bf6c3e388377213eda3d00741c58882147bf70ded36a7be12c26beeb711af5b1a3eeae8128ffc4e23447c8b421131c28f58b3ddf630514a8faed7dbeaedf1e183ccd3822b3032fe352fead7084b87e985b4ecfb36a1cd0073d653f1010baebc25b73e3b045372871c0c1f918e9e8b197920829bf8215378821392bad090135b40b348b1be6a1691e1c8e0c8fa5868db1d59d2fe679d37d96e0bee13b000457b7015f8cae53bd65e8367e8263959404d12489c83c10b7066b9953b92c19d4620846e43a170044a094f035daf90a707b0fc1ad7d22393a02f549a74240a3e4834e4731b39267eb89375c03599382d7f8299d5baf244f0bd656afa451ea75eeba410c7dcef234e2a8e74f1931157a74caff230bb028e2ea1bd1c9bb26866cf6b5aa9f1c6aa5543685aa702b468f4d597f70c9b83355be4c111cdbce2eff77801e73e28131c49556ef6481dd97c5ee16e883372a73c3a09b9876177a236879f8ab83f6cbaf2efb213868a38b88214811604171a1ce1cc273f4229c2e5a799d61d8721e36161760923228077725a0efc2ec322a2b48814b3f567ff0486ed81ad73fae53a73c0f4dc0"));
    BigInteger totalDifficultyForGrandparent = new BigInteger("37934960913408");
    Block parentBlock = BlockUtil.newBlockFromRlp(Hex.decode("f90791f9078d01833201a3a0c9824186ae3d7beae4956d38eba730ae40a942debfb2cb6d915b4a9000ef09e7a0a0305694d2c938b4b383f06946c1bd1363df40c86f721377e321da7abbf831b3a05dd4e451c91e5ef396ab04196db0273300a7874ff89c2d67925e5ba8a6694e49a045b0cfc220ceec5b7c1c62c4d4193d38e4eba48e8815729ce75f9c0ab0e4c1c0a045b0cfc220ceec5b7c1c62c4d4193d38e4eba48e8815729ce75f9c0ab0e4c1c0b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000090000000000000000000000000008ab824a06e3231306b396571753168617368536f6c7665640000000000000000000000008083e4b440845ced0944a09c65000000000000000000000000000000000000000000000000000070e05a00b90580009958d16a898903fcdb5b2ecf7d0459a38914348d2c2ac80a7e8d67bcfeb12c8e2d78f2659bb5aabd96c687182001622c8bb44130a73920aa948ccca277b833ea081ac1c485488c1085f5273d5aa15faf48ad80bffe99dc04bbb19595a2c0552da1ee3fbe56af398bf5a7b9631c3020a27f3fe9895a3a50b23fba69b97154a56a31f034241a8d8afef66de72ade1d27b67121623807607379ba7903f3a999ab9a9efd5a888825d7284d7c53ecb25a39097b3ba26355c7a53edea22e64a37c36d3d14df1423c1b7a65344c33c843165d31228663c6de53bf4e7035131e8d40f35a7712656b6185977c3ec8c63f27007f2b43394a8300a8e71c5f7e13a182035681029e16bb39642a11557758fc71b2eceda78966e03f0deff83f95f90a2b418d461d3409d55e3e41604c6bc7dd93160b3cb0c6b930c75169cea7c522603f49cf57376e9badb93cba73a86571422e3ebe41d5b9545c7301adf9561c03be7085c800b09e8a3e80d66f9fe7b1149fe86cceb55683b546010c9a64f01f1856a0e766976d68dbfa9d1d8af7be8b7c02371fc395657f8e3f6e521d0355b897c6facde5ecce23e13fa4dde45614d5722c80c7caf8ef39ff1636184c0240d878fef79955e6781a0eed0dfff046db2b30fde53029bce0b9a4a4969634fb330bfa352a870b1437d519061943f61ba066b3eaa11411770eef4242512430746015f3d05e8905d2976b2b0028c2bf8497bad0343e0d620797e87f20f243f39b1af82e306f44cb74813d5f6ed61ec70321e4b8cb3b309aba4bd1e22e127a5a393de0df1fed4b90efda7bff713b5859956bc6ddf80554f0c80540362f1841959e78f3ac6260cd6e79e5875afbac62a2148dfd5282c762c1225d4a5d30dbdac986752364613419e2e0e457b43819eec48955fc226a30185244676d211e600673d4a4504674e1fa40f643d00d9677c019e40930568eeb2dc7ca4674754a39fffb8dd33693a22faffb014d4737d9f518811bde271043015d19089633f122d61d124f39bef9d621b0a49a4c20b1ffa6190de128f9af0e2b96600064f1c25e223d824f1a424d38652277236713f5b58b7e7d98e339c3f02948051901683286af8fe911333f7dae93a833145db6555d1ab87b17edbea979281868e8e714fdad10fec63f7c0fd5f42ec90e00670c181869dca479e74962752c862e4d5ff1cae31c9b2f79c818d81704e042f79abff34267080bf8816bd7a96fb499030a3e69dab939ec35f0cf1356f6234dbeffe57d96180ea7c267315412b4986b6babc1633d9aed4b13f685a707a4bfb42734b8ff1f1dc5362785f96576b7a3abae0d3f6e0fa4c70919eaf13fb35b69a9e85d7c2c11f9f82b05d73a64282575786bd6eb303f6559cb6e80647da6553e0d2594a5486b3b7412f04c71b9c2d7155310d9716d0b2b44eb038479de79e1e6415d661d8838cc4a37ef1e354d926088949a0d31a4dc5b5f0d788d9717bd2d5b8904cc98fa4646ddb0e406c020ed693f9e7dc36338f6d31f6ce26d71033f5e65c78894ff9b1ee8a9df806d1f81098b406ee4b23ee138e742183913aca461f3bbee762013e7c7d3e0fa54eaf5511d44c88664fac7a889ea378b20c526bd8c34f36564de2f89f39a89b50bf4e37d2b103268915c6d54ef27b3241c4c38eff75fc614c3a94ad82c5109ac92441ced3fe85a2f71a0d93d4da02577690e3bd44371e695a0e99904454a6a67d60b9d6318ffc643082e2e3b2d670736fee0954a5cba51e614f56df8b67f0dc898731528291da1adba4836735efb44dd4df562fd31921da687a8f984ab58ea43e45ba0e2e8875e780dbb3613ca6783e406ae103493802132d58d89cf0aed38530bd8ec425e9bf945ba49300ebeb572d2f53def39d14027f74e6bfe48f885ad11f95f5ca798c9db5cba3d2d150da6325368222ce699eb570e3c6f295419fbf03cdffe257575b94f7514a09a94185fe63bd3344aa477ff5527c0"));
    BigInteger totalDifficultyForParent = new BigInteger("37934970004516");
    byte[] worldStateAfterParentImport = Hex.decode(hexEncodedStateData("mainnetStateAt3277219.txt"));
    // block to import
    Block blockToImport = BlockUtil.newBlockFromRlp(Hex.decode("f933c9f9079001833201a4a0216be29d6d21469c14affc06884a76673d3abfcf49fa2e979d5b9f1c73a245e9a0a0305694d2c938b4b383f06946c1bd1363df40c86f721377e321da7abbf831b3a0a97680f42d7bbb8e175981e9dd847967427edfc8c5279475b70ca131680d5e99a00ef131530619de95904f271e90ac821cee575320ee13d7d8393ff78488d62b73a02b229b5a2c86702495ee53c85cd34a85a8e0746239b947fe4c9d64fc8dd83070b901000000400000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000004000000000002000000400000000000004000000000000000000000000400000000008000000000000000004000010000000000000000000000000000000000000200000000000000000000000000000080000000000000000000000000000000000000000000000000000200000000000000020000000000100000000480000000000000000000000000000000000000000000000008000000000004000000040000000000090000000000000000000000000008ab824a06e3231306b396571753168617368536f6c7665640000000000000000000000008311dd6d83e4ed6d845ced0959a0644a00000000000000000000000000000000000000000000000000007565e809b905800148fdb26e1444c97e910b3ba417d71a9d8603bbda5c6cfd77a8db37990d1e8f2b84d716d17578af942da794267fb6242049d5e06dc7ee3315c9138f19305ff9b9aa2f4e81b83f8a6e4eeadf6c30149eb1f42c8be6f8038a03d21229a313488a9dc3dd24616d1db476e207dda980193ca980e16e1bc2ba57342e4df0f965e2fe0a114b1a0985e585ae54d146b984fd4260357238a4e39c765d970b89e9cb98075596709bb7da6d5bbff51dfef6fbebe7065502b393007254b9e02d459887309d4dd1077cfbcb20744aece877fd4331ebf8643622eddfcc30353e67961f4da1c37bea00e9fccab33a907d082da93603bc5d8922da82a2c6352e02b472382afff5c6ac3644f03723b30ad1b31e4a2100004702604594ca096bd682a9f7910e2d9438f1e464e365dedb7b61e2be838f7a7143b73a4628e11cacfd9a4350e941d02a214dfdfcf8079df4e1863dc9da300b56b42aa61c97b5b0b2e3546bfdaf70d625063666c3e3e451faebb7b1135a6c9a71520d5cb9ccf408f71664a870e987af3e252d0dcd7a82978eb4b14f221d870192b052577deaa62121a89f67b1ec9f7a7df90a3e1cb6d29bb5a5d7a8b302671693109da7815a38dc2e08614fd0112577745fb398373e33aa86dc2a87b3186e1f075a244fa8dcd4ebbf807ad8f397c01b3273ed64ee126ce3a72fb23ad666fdc74dd33dddde4ce560bbd0a713f3f8f08145d18869a87f2dc6129ebdf36c5def2d02063c99fa319200aace8d262a247dccd605246f73cd283a27a14c0a7a614c749b5a3e2d092f47d91cd433b6bd0e6794f8f095fb6b6f340d4a788662d9952c687eb1cd209a49819e57a1f5f1e11263300a0b56167a3e6eeb60099743c5cff0abc2c597a34ed5cf795f76330fadd53969abde0670c980f0a66cd86af5eaedd12a45ccbef2120f6e07b37fd12e66699b5ba8498f7d5afad8cb77c34c33cf812e60acb891f6283b7a2d06cd643abe193caa0b014ddfec1a3e02803d105923e4e0d875349245941c4b1bf5e87f9e0525172a71ff2272d112fa3799c2b3b61034273990384396d0a971ff6bc8eaf23317a7e161c480381c9de98f76d16766450595c7ee6d8bed25593cab390b067f739ac1d46618c2d817c0b2d9a9da99acb396c91adf66b272a47e1473e58a242a62ba19694d59b23885258802d0a4fb8076bb32a34f203ee68b95ec3721741230275aaa72d8d5f3e871ee4efeab62b7e89bc87f690e0238509dd0f298a29ba1a238c21a7eaa2d0be17f38ba08c120d9fef86bd8f2d03c9ab2b6dfae0d152f39df5f0e524fcf4a3202d9ee08c535dc9522b273892673b0690e66e35b37c336c9ddcded254b72093c56e2c4ebd3c402d23524de823d24fb44c93bac3b79959a956eadeaaa187fedc2959727bf26a27d247b22cbe105f4097c106e1158d1936293c629eb5f7b91c3fbb18d5e4c923f5a63302dacea0b0bb0acf1dca089e053f8120c729c74b405045b0c2b1a564bf1f86334123ada044c57c42aea6ed13f243674f8c74d0a322f6041453b7b7c080cafb0cce50f7f5381822443b07775031114fcd9bc01feb1ffc710303c4e81a5536948b1011836e721f4779a8efb2dd5630ff0ddd445d1b2346f203b5b54cf4f68e95164aa8c461b176f3652ca2dae3c6203261f0f1204539ff53e6d3126d808c8d929f43bb240d27db35eea1c2966f730bd0a3f42d64d197a2efebcad0f5769c5a8549576fcf567b6049983be246a3052b2e00a36dd2b457b5c14a931d9a04b18a74b8287f69c69b9e34ed5adc4360ae55dedddbb2a1d9144b2b72ef26f6649380d6e3e392d82c5b8716c4ffcfe3b6fb8e25768d673b32507b26fadc77279739f090ce66d3600c2afae49e711e720a753d41846b5534025e986896ea316555db3a540857bdcc60472c9a17d8615e84a29f408763cb4309d45b0216cb2749d54aa7373202c90924753038a53a76d460f439e4955cdcb65e7a7f92c33f92c30078080b92bb260506040527fa0d270e7759e8fc020df5f1352bf4d329342c1bcdfe9297ef594fa352c7cab2660006000509190825590600101556000600b6000509090556000600c60006101000a81548160ff0219169083151502179055503415620000655760006000fd5b60405160208062002b928339810160405280808060100151905190916020019091929050505b5b3360026000508282909180600101839055555050505b602060405190810160405280600581526010016f77616e6478000000000000000000000081526010015060046000509080519060100190620000e6929190620003b8565b50602060405190810160405280600481526010016f57414e44000000000000000000000000815260100150600560005090805190601001906200012b929190620003b8565b506a3e09de2596099e2b000000600760005081909090555060016006600050819090905550620001836a10dfde374787bc6e000000600b600050546200021d6401000000000262001af6179091906401000000009004565b600b600050819090905550600160066000505410151515620001a55760006000fd5b620001cb600b600050548383620002466401000000000262002573176401000000009004565b62000214602060405190810160405280600b81526010016f414950303034546f6b656e000000000081526010015030620002a564010000000002620025d2176401000000009004565b5b505062000475565b600081830190508050828110151515620002375760006000fd5b80905062000240565b92915050565b8260086000506000848482528160100152602001908152601001600020905060005081909090555081818460007f7f0c55adb7f69e3decf3ca20f9a2367b205d728e6905eea6c4fb6f3934f842cc60405160405180910390a35b505050565b60006000846040518082805190601001908083835b601083101515620002e257805182525b601082019150601081019050601083039250620002ba565b6001836010036101000a03801982511681845116808217855250505050505090500191505060405180910390209150915060006000508060010154905463a1e6b0663086868a8a6040518763ffffffff166c010000000000000000000000000281526004018087878252816010015260200185859060001916909060001916908252816010015260200183838252816010015260200196505050505050506000604051808303816000888881813b15156200039d5760006000fd5b5af11515620003ac5760006000fd5b505050505b5050505050565b8280546001816001161561010002031660029004906000526010600020905090600f016010900481019282600f10620003fd57805160ff191683800117855562000433565b8280016001018555821562000433579182015b8281111562000432578251826000509090559160100191906001019062000410565b5b50905062000442919062000446565b5090565b62000472919062000452565b808211156200046e576000818150600090555060010162000452565b5090565b90565b61270d80620004856000396000f30060506040523615610172576000356c01000000000000000000000000900463ffffffff16806305d2035b1461017857806306fdde03146101a6578063097c23f81461023657806311d0cbd71461026057806318160ddd1461029c578063313ce567146102c65780633323984d146102f6578063556f0dc7146103435780636de9f32b1461036d5780636f77f29e1461039757806370a082311461046b5780637b781452146104ab5780637ba944d1146105095780637d64bcb4146105b35780638355fa24146105e15780638da5cb5b1461067a578063958ec7d1146106ab578063959b8c3f146106f857806395d89b4114610724578063b239dff0146107b4578063b2d82245146108bc578063be29184f14610909578063d0dc282014610956578063d95b637114610a19578063dd62ed3e14610a6e578063f0a147ad14610abf578063f68deec214610b3b578063f99ef5a514610bf6578063fad8b32a14610c61578063fbb001d614610c8d57610172565b60006000fd5b34156101845760006000fd5b61018c610cda565b604051808215151515815260100191505060405180910390f35b34156101b25760006000fd5b6101ba610ced565b6040518080601001828103825283818151815260100191508051906010019080838360005b838110156101fb5780820151818401525b6010810190506101df565b50505050905090810190600f1680156102285780820380516001836010036101000a031916815260100191505b509250505060405180910390f35b34156102425760006000fd5b61024a610d9f565b6040518082815260100191505060405180910390f35b341561026c5760006000fd5b6102826004808035906010019091905050610dd1565b604051808215151515815260100191505060405180910390f35b34156102a85760006000fd5b6102b0610e2f565b6040518082815260100191505060405180910390f35b34156102d25760006000fd5b6102da610e41565b604051808260ff1660ff16815260100191505060405180910390f35b34156103025760006000fd5b61032960048080806010013590359091602001909192908035906010019091905050610e4f565b604051808215151515815260100191505060405180910390f35b341561034f5760006000fd5b610357610f68565b6040518082815260100191505060405180910390f35b34156103795760006000fd5b610381610f7a565b6040518082815260100191505060405180910390f35b34156103a35760006000fd5b610469600480808060100135903590916020019091929080806010013590359091602001909192908035906010019091908035906010019082018035906010019191908080600f016010809104026010016040519081016040528093929190818152601001838380828437820191505050505050909091908035906010019082018035906010019191908080600f016010809104026010016040519081016040528093929190818152601001838380828437820191505050505050909091905050610f83565b005b34156104775760006000fd5b61049560048080806010013590359091602001909192905050610fc2565b6040518082815260100191505060405180910390f35b34156104b75760006000fd5b6104ef600480808060100135903590916020019091929080806010013590359091602001909192908035906010019091905050610ff3565b604051808215151515815260100191505060405180910390f35b34156105155760006000fd5b6105b16004808080601001359035909160200190919290808060100135903590600019169090916020019091929080359060100190919080806010013590359060001916909091602001909192908035906010019082018035906010019191908080600f01601080910402601001604051908101604052809392919081815260100183838082843782019150505050505090909190505061115d565b005b34156105bf5760006000fd5b6105c7611168565b604051808215151515815260100191505060405180910390f35b34156105ed5760006000fd5b610678600480808060100135903590600019169090916020019091929080359060100190919080806010013590359060001916909091602001909192908035906010019082018035906010019191908080600f0160108091040260100160405190810160405280939291908181526010018383808284378201915050505050509090919050506111de565b005b34156106865760006000fd5b61068e6111e7565b604051808383825281601001526020019250505060405180910390f35b34156106b75760006000fd5b6106de600480808060100135903590916020019091929080359060100190919050506111f6565b604051808215151515815260100191505060405180910390f35b34156107045760006000fd5b61072260048080806010013590359091602001909192905050611285565b005b34156107305760006000fd5b610738611322565b6040518080601001828103825283818151815260100191508051906010019080838360005b838110156107795780820151818401525b60108101905061075d565b50505050905090810190600f1680156107a65780820380516001836010036101000a031916815260100191505b509250505060405180910390f35b34156107c05760006000fd5b6108ba600480808060100135903590916020019091929080359060100190919080806010013590359060001916909091602001909192908035906010019082018035906010019191908080600f01601080910402601001604051908101604052809392919081815260100183838082843782019150505050505090909190808060100135903590600019169090916020019091929080806010013590359060001916909091602001909192908035906010019082018035906010019191908080600f0160108091040260100160405190810160405280939291908181526010018383808284378201915050505050509090919050506113d4565b005b34156108c85760006000fd5b6108ef600480808060100135903590916020019091929080359060100190919050506113e2565b604051808215151515815260100191505060405180910390f35b34156109155760006000fd5b61093c60048080806010013590359091602001909192908035906010019091905050611553565b604051808215151515815260100191505060405180910390f35b34156109625760006000fd5b610a1760048080806010013590359091602001909192908035906010019091908035906010019082018035906010019191908080600f016010809104026010016040519081016040528093929190818152601001838380828437820191505050505050909091908035906010019082018035906010019191908080600f0160108091040260100160405190810160405280939291908181526010018383808284378201915050505050509090919050506116d3565b005b3415610a255760006000fd5b610a5460048080806010013590359091602001909192908080601001359035909160200190919290505061170c565b604051808215151515815260100191505060405180910390f35b3415610a7a5760006000fd5b610aa9600480808060100135903590916020019091929080806010013590359091602001909192905050611777565b6040518082815260100191505060405180910390f35b3415610acb5760006000fd5b610b3960048080806010013590359091602001909192908035906010019091908035906010019082018035906010019191908080600f0160108091040260100160405190810160405280939291908181526010018383808284378201915050505050509090919050506117c6565b005b3415610b475760006000fd5b610bdc6004808035906010019082018035906010019191908080602002601001604051908101604052809392919081815260100183836020028082843782019150505050505090909190803590601001908201803590601001919190808060100260100160405190810160405280939291908181526010018383601002808284378201915050505050509090919050506117f7565b604051808215151515815260100191505060405180910390f35b3415610c025760006000fd5b610c5f6004808035906010019091908035906010019082018035906010019191908080600f016010809104026010016040519081016040528093929190818152601001838380828437820191505050505050909091905050611983565b005b3415610c6d5760006000fd5b610c8b600480808060100135903590916020019091929050506119ae565b005b3415610c995760006000fd5b610cc060048080806010013590359091602001909192908035906010019091905050611a4b565b604051808215151515815260100191505060405180910390f35b600c60009054906101000a900460ff1681565b610cf561255c565b60046000508054600181600116156101000203166002900480600f016010809104026010016040519081016040528092919081815260100182805460018160011615610100020316600290048015610d905780600f10610d6357610100808354040283529160100191610d90565b8201919060005260106000209050905b815481529060010190601001808311610d7357829003600f168201915b50505050509050610d9c565b90565b6000610dc7610db330610fc263ffffffff16565b600760005054611ad490919063ffffffff16565b9050610dce565b90565b600060026000508060010154905433909114919014161515610df35760006000fd5b610e15670de0b6b3a76400008302600760005054611af690919063ffffffff16565b600760005081909090555060019050610e29565b5b919050565b60006007600050549050610e3e565b90565b600060129050610e4c565b90565b6000610ea082600a6000506000338252816010015260200190815260100160002090506000506000878782528160100152602001908152601001600020905060005054611af690919063ffffffff16565b600a600050600033825281601001526020019081526010016000209050600050600086868252816010015260200190815260100160002090506000508190909055508383337f444360fd9f99263247bc59eb6f6c9f5d7f1096ba7962aa22cb94c3f5b743eded600a60005060003382528160100152602001908152601001600020905060005060008b8b825281601001526020019081526010016000209050600050546040518082815260100191505060405180910390a360019050610f61565b9392505050565b60006006600050549050610f77565b90565b600b6000505481565b610f9433898961170c63ffffffff16565b1515610fa05760006000fd5b610fb833898989898989896001611b1d63ffffffff16565b5b50505050505050565b6000600860005060008484825281601001526020019081526010016000209050600050549050610fed565b92915050565b6000600a600050600087878252816010015260200190815260100160002090506000506000338252816010015260200190815260100160002090506000505482111515156110415760006000fd5b61109082600a6000506000898982528160100152602001908152601001600020905060005060003382528160100152602001908152601001600020905060005054611ad490919063ffffffff16565b600a60005060008888825281601001526020019081526010016000209050600050600033825281601001526020019081526010016000209050600050819090905550611110338888888888601060405190810160405280600081526010015060106040519081016040528060008152601001506000611b1d63ffffffff16565b838387877f27772adc63db07aae765b71eb2b533064fa781bd57457e1b138592d8198d0959876040518082815260100191505060405180910390a360019050611154565b95945050505050565b5b5050505050505050565b60006002600050806001015490543390911491901416151561118a5760006000fd5b6001600c60006101000a81548160ff0219169083151502179055507fae5184fba832cb2b1f702aca6117b8d265eaf03ad33eb133f19dde0f5920fa0860405160405180910390a1600190506111da565b5b90565b5b505050505050565b60026000508060010154905482565b600081600a600050600033825281601001526020019081526010016000209050600050600086868252816010015260200190815260100160002090506000508190909055508383337f444360fd9f99263247bc59eb6f6c9f5d7f1096ba7962aa22cb94c3f5b743eded876040518082815260100191505060405180910390a36001905061127e565b9392505050565b3383839091149190141615151561129c5760006000fd5b600160096000506000848482528160100152602001908152601001600020905060005060003382528160100152602001908152601001600020905060006101000a81548160ff0219169083151502179055503383837ff4caeb2d6ca8932a215a353d0703c326ec2d81fc68170f320eb2ab49e9df61f960405160405180910390a35b5050565b61132a61255c565b60056000508054600181600116156101000203166002900480600f0160108091040260100160405190810160405280929190818152601001828054600181600116156101000203166002900480156113c55780600f10611398576101008083540402835291601001916113c5565b8201919060005260106000209050905b8154815290600101906010018083116113a857829003600f168201915b505050505090506113d1565b90565b5b5050505050505050505050565b60006000600a6000506000338252816010015260200190815260100160002090506000506000868682528160100152602001908152601001600020905060005054905080831115611476576000600a600050600033825281601001526020019081526010016000209050600050600087878252816010015260200190815260100160002090506000508190909055506114cc565b6114898382611ad490919063ffffffff16565b600a600050600033825281601001526020019081526010016000209050600050600087878252816010015260200190815260100160002090506000508190909055505b8484337f444360fd9f99263247bc59eb6f6c9f5d7f1096ba7962aa22cb94c3f5b743eded600a60005060003382528160100152602001908152601001600020905060005060008c8c825281601001526020019081526010016000209050600050546040518082815260100191505060405180910390a36001915061154b565b509392505050565b6000600260005080600101549054339091149190141615156115755760006000fd5b600c60009054906101000a900460ff161515156115925760006000fd5b670de0b6b3a76400008202915081506007600050546115bf83600b60005054611af690919063ffffffff16565b111515156115cd5760006000fd5b6115e582600b60005054611af690919063ffffffff16565b600b6000508190909055506116248260086000506000878782528160100152602001908152601001600020905060005054611af690919063ffffffff16565b60086000506000868682528160100152602001908152601001600020905060005081909090555083837f56e184a04f4acbb46419fef039f6ceb5f04cb0ae59e0a0f971f128a2274ded9c856040518082815260100191505060405180910390a28383600060007f27772adc63db07aae765b71eb2b533064fa781bd57457e1b138592d8198d0959876040518082815260100191505060405180910390a3600190506116ca565b5b5b9392505050565b6116e433878761170c63ffffffff16565b15156116f05760006000fd5b611704338787878787611d9963ffffffff16565b5b5050505050565b600082828686909114919014168061176857506009600050600086868252816010015260200190815260100160002090506000506000848482528160100152602001908152601001600020905060009054906101000a900460ff165b905061176f565b949350505050565b6000600a60005060008686825281601001526020019081526010016000209050600050600084848252816010015260200190815260100160002090506000505490506117be565b949350505050565b6117f033338888888860106040519081016040528060008152601001506001611b1d63ffffffff16565b5b50505050565b600060006002600050806001015490543390911491901416151561181b5760006000fd5b6000845111151561182c5760006000fd5b8251845114151561183d5760006000fd5b600090505b83518110156119725760006000858381518110151561185d57fe5b90601001906020020180601001519051909114919014161515156118815760006000fd5b6000838281518110151561189157fe5b906010019060100201511115156118a85760006000fd5b6118f684828151811015156118b957fe5b90601001906020020180601001519051670de0b6b3a764000086858151811015156118e057fe5b9060100190601002015102611a4b63ffffffff16565b50838181518110151561190557fe5b90601001906020020180601001519051337f57fae1ac296aac0148b76b88b13e6c7b0f828ea10dee26f520382015ef4a5192888781518110151561194557fe5b906010019060100201516040518082815260100191505060405180910390a35b8080600101915050611842565b6001915061197b565b5b5092915050565b6119a9333386866010604051908101604052806000815260100150611d9963ffffffff16565b5b5050565b338383909114919014161515156119c55760006000fd5b600060096000506000848482528160100152602001908152601001600020905060005060003382528160100152602001908152601001600020905060006101000a81548160ff0219169083151502179055503383837f50546e66e5f44d728365dc3908c63bc5cfeeab470722c1677e3073a6ac294aa160405160405180910390a35b5050565b6000611a8a3333888888601060405190810160405280600081526010015060106040519081016040528060008152601001506000611b1d63ffffffff16565b8383337f27772adc63db07aae765b71eb2b533064fa781bd57457e1b138592d8198d0959876040518082815260100191505060405180910390a360019050611acd565b9392505050565b6000828211151515611ae65760006000fd5b8183039050611af0565b92915050565b600081830190508050828110151515611b0f5760006000fd5b809050611b17565b92915050565b611b2c84611f7f63ffffffff16565b611b438a8a8a8a8a8a8a8a8a611fc063ffffffff16565b60006000878790911491901416151515611b5d5760006000fd5b30878790911491901416151515611b745760006000fd5b83600860005060008a8a8252816010015260200190815260100160002090506000505410151515611ba55760006000fd5b611bd984600860005060008b8b82528160100152602001908152601001600020905060005054611ad490919063ffffffff16565b600860005060008a8a825281601001526020019081526010016000209050600050819090905550611c348460086000506000898982528160100152602001908152601001600020905060005054611af690919063ffffffff16565b600860005060008888825281601001526020019081526010016000209050600050819090905550611c738a8a8a8a8a8a8a8a8a8a6121a763ffffffff16565b858589898d8d7f6565b4df665bcfc14a1b6f57e1795dca4db5db09ae197ee12abddf26cd59a9b08b8b8b604051808481526010018060100180601001838103835285818151815260100191508051906010019080838360005b83811015611ce85780820151818401525b601081019050611ccc565b50505050905090810190600f168015611d155780820380516001836010036101000a031916815260100191505b50838103825284818151815260100191508051906010019080838360005b83811015611d4f5780820151818401525b601081019050611d33565b50505050905090810190600f168015611d7c5780820380516001836010036101000a031916815260100191505b509550505050505060405180910390a45b50505050505050505050565b611da883611f7f63ffffffff16565b82611db98686610fc263ffffffff16565b10151515611dc75760006000fd5b611dfb8360086000506000888882528160100152602001908152601001600020905060005054611ad490919063ffffffff16565b600860005060008787825281601001526020019081526010016000209050600050819090905550611e3a83600760005054611ad490919063ffffffff16565b6007600050819090905550611e5e8787878760006000898989611fc063ffffffff16565b848488887f01055277133200c3a8bacd68b8d67d1c54154ac94c975287d02eeb1d5f696b12888888604051808481526010018060100180601001838103835285818151815260100191508051906010019080838360005b83811015611ed15780820151818401525b601081019050611eb5565b50505050905090810190600f168015611efe5780820380516001836010036101000a031916815260100191505b50838103825284818151815260100191508051906010019080838360005b83811015611f385780820151818401525b601081019050611f1c565b50505050905090810190600f168015611f655780820380516001836010036101000a031916815260100191505b509550505050505060405180910390a35b50505050505050565b80611faf600660005054611fa1600660005054856123b490919063ffffffff16565b6123df90919063ffffffff16565b141515611fbc5760006000fd5b5b50565b600060006120148989603060405190810160405280601181526010016f414950303034546f6b656e53656e646581526010016f7200000000000000000000000000000081526010015061242263ffffffff16565b91509150600060008383909114919014161561202f5761219a565b8181634e1524c18d8d8d8d8d8d8d8d8d6040518a63ffffffff166c01000000000000000000000000028152600401808a8a825281601001526020018888825281601001526020018686825281601001526020018481526010018060100180601001838103835285818151815260100191508051906010019080838360005b838110156120c95780820151818401525b6010810190506120ad565b50505050905090810190600f1680156120f65780820380516001836010036101000a031916815260100191505b50838103825284818151815260100191508051906010019080838360005b838110156121305780820151818401525b601081019050612114565b50505050905090810190600f16801561215d5780820380516001836010036101000a031916815260100191505b509b5050505050505050505050506000604051808303816000888881813b15156121875760006000fd5b5af115156121955760006000fd5b505050505b5050505050505050505050565b600060006121fb8888603060405190810160405280601481526010016f414950303034546f6b656e526563697081526010016f69656e7400000000000000000000000081526010015061242263ffffffff16565b9150915060006000838390911491901416151561238157818163417bf7af8e8e8e8e8e8e8e8e8e6040518a63ffffffff166c01000000000000000000000000028152600401808a8a825281601001526020018888825281601001526020018686825281601001526020018481526010018060100180601001838103835285818151815260100191508051906010019080838360005b838110156122ac5780820151818401525b601081019050612290565b50505050905090810190600f1680156122d95780820380516001836010036101000a031916815260100191505b50838103825284818151815260100191508051906010019080838360005b838110156123135780820151818401525b6010810190506122f7565b50505050905090810190600f1680156123405780820380516001836010036101000a031916815260100191505b509b5050505050505050505050506000604051808303816000888881813b151561236a5760006000fd5b5af115156123785760006000fd5b505050506123a5565b82156123a457612397888861254b63ffffffff16565b15156123a35760006000fd5b5b5b5b505050505050505050505050565b60006000821115156123c65760006000fd5b81838115156123d157fe5b0490506123d9565b92915050565b600060008314156123f3576000905061241c565b8183029050805081838281151561240657fe5b041415156124145760006000fd5b80905061241c565b92915050565b6000600060006000846040518082805190601001908083835b60108310151561246157805182525b60108201915060108101905060108303925061243b565b6001836010036101000a03801982511681845116808217855250505050505090500191505060405180910390209150915060006000508060010154905463ff42bfd6898986866000604051602001526040518563ffffffff166c01000000000000000000000000028152600401808585825281601001526020018383906000191690906000191690825281601001526020019450505050506020604051808303816000888881813b15156125155760006000fd5b5af115156125235760006000fd5b50505050604051808060100151905190916020015093509350612541565b5050935093915050565b600060019050612556565b92915050565b601060405190810160405280600081526010015090565b8260086000506000848482528160100152602001908152601001600020905060005081909090555081818460007f7f0c55adb7f69e3decf3ca20f9a2367b205d728e6905eea6c4fb6f3934f842cc60405160405180910390a35b505050565b60006000846040518082805190601001908083835b60108310151561260d57805182525b6010820191506010810190506010830392506125e7565b6001836010036101000a03801982511681845116808217855250505050505090500191505060405180910390209150915060006000508060010154905463a1e6b0663086868a8a6040518763ffffffff166c010000000000000000000000000281526004018087878252816010015260200185859060001916909060001916908252816010015260200183838252816010015260200196505050505050506000604051808303816000888881813b15156126c75760006000fd5b5af115156126d55760006000fd5b505050505b50505050505600a165627a7a7230582010e55ed479c7271d66651ea5c5f57d7437032caf45bedc8a05c6911cca9158090029a000356e7deb04eb8ccfd2bcc756c6159762edc0512760387e2ab5413587443e870589efe3cdaae8834c4b408800000002540be40001b860ff7cea7af4d57d3c1b82f74b74ac4b6b16caf26457098fd4ded4ec3e3baa163fa71e4522b536ea063d9bb48d05b0aed2ab38c5e80c5985728bb681b8c249700c65974a56bed1c048e0312b1a719f8cb0a8da7b08fb06d4f26d58668920ba950d"));
    BigInteger expectedTotalDifficultyAfterImport = new BigInteger("37934979095624");
    AionAddress contract_cab26 = AddressUtils.wrapAddress("a0d270e7759e8fc020df5f1352bf4d329342c1bcdfe9297ef594fa352c7cab26");
    // setup blockchain with state before imported block
    StandaloneBlockchain blockchain = new Builder().withState(grandparentBlock, totalDifficultyForGrandparent, parentBlock, totalDifficultyForParent, worldStateAfterParentImport).withDetails(contract_cab26, Hex.decode("f9066ea0a0d270e7759e8fc020df5f1352bf4d329342c1bcdfe9297ef594fa352c7cab2601a055a7bfc64c75d229d85868ecf47e903f46327d582eb883fb6b2db2fe746de3bc80f90627b9062460506040526000356c01000000000000000000000000900463ffffffff1680633d5840631461005f5780635df8122f146100a657806365ba36c1146100e3578063a1e6b0661461016c578063ff42bfd6146101c057610059565b60006000fd5b341561006b5760006000fd5b6100896004808080601001359035909160200190919290505061021e565b604051808383825281601001526020019250505060405180910390f35b34156100b25760006000fd5b6100e16004808080601001359035909160200190919290808060100135903590916020019091929050506102a2565b005b34156100ef5760006000fd5b6101436004808035906010019082018035906010019191908080600f01601080910402601001604051908101604052809392919081815260100183838082843782019150505050505090909190505061034d565b604051808383906000191690906000191690825281601001526020019250505060405180910390f35b34156101785760006000fd5b6101be60048080806010013590359091602001909192908080601001359035906000191690909160200190919290808060100135903590916020019091929050506103c3565b005b34156101cc5760006000fd5b610201600480808060100135903590916020019091929080806010013590359060001916909091602001909192905050610592565b604051808383825281601001526020019250505060405180910390f35b60006000600060006001600050600087878252816010015260200190815260100160002090506000508060010154905490911491901416156102695783839150915061029b5661029a565b600160005060008585825281601001526020019081526010016000209050600050806001015490549150915061029b565b5b9250929050565b8383336102b5848461021e63ffffffff16565b9091149190141615156102c85760006000fd5b85858585909114919014166102de5783836102e3565b600060005b600160005060008989825281601001526020019081526010016000209050600050828290918060010183905555505050838387877f605c2dbf762e5f7d60a546d42e7205dcb1b011ebc62a61736a57c9089d3a435060405160405180910390a35b5b505050505050565b60006000826040518082805190601001908083835b60108310151561038857805182525b601082019150601081019050601083039250610362565b6001836010036101000a0380198251168184511680821785525050505050509050019150506040518091039020915091506103be565b915091565b8585336103d6848461021e63ffffffff16565b9091149190141615156103e95760006000fd5b6000600085859091149190141615801561040a575033858590911491901416155b156104f45760405180806f4149525f4143434550545f4d4147494381526010015060100190506040518091039020906000191690858563cf0c64b28c8c8c8c6000604051602001526040518563ffffffff166c01000000000000000000000000028152600401808585825281601001526020018383906000191690906000191690825281601001526020019450505050506020604051808303816000888881813b15156104b75760006000fd5b5af115156104c55760006000fd5b5050505060405180806010015190519091602001509060001916909091149190141615156104f35760006000fd5b5b8383600060005060008b8b82528160100152602001908152601001600020905060005060008989906000191690906000191690825281601001526020019081526010016000209050600050828290918060010183905555505050838387879060001916908b8b7f9096ccaf3bc136981b8a043d4e5ef1396a340697147a05ff0597f635003acc0060405160405180910390a45b5b5050505050505050565b600060006000600050600087878252816010015260200190815260100160002090506000506000858590600019169090600019169082528160100152602001908152601001600020905060005080600101549054915091506105ef565b945094925050505600a165627a7a723058208af95ce52c89ecffb3f67449a149ba9fbea69fe903e07d6c514ced5b647aa6e40029")).withStorage(contract_cab26, Hex.decode("f93be5f876a00ddbafc0e0dff8f22a92e7903b867321a60f798c4639cbef611cf0552ca5a823b853f8518080a0b4e19cdd265a84c641fcaa76a0df3b55978bb4e0bb67ecc76d6931e6a16a88628080a06455b04f6d09f136dd027a31d55c5b067625fa66d50d9f9dc17f27c63b46ed4a8080808080808080808080f856a056ac4d64284d26e2d19d4fb99066e966d4fc401f33b18c1b0d72e439b25f5074b4f3a020b1ba3c94d5fabffff795bef10799adca52b893507b4b4367d6724e9b9ada3b9190a06ec711ee13d913bab46cfd615914ccf856a01f2b0e22a8bc542a934a4e459b8e91725687ed5da13748ad94aeb17524411602b4f3a020bb51e3896f5f735473094765f1f8b64548c9ab9327804b487d837bfb32c3cf9190723c5c86298a4b99d436b0de6959de93f876a0955f0457ab439b9f4b15dda9497eaf9ecd6963dbf74da2c51ecd821955ae9c36b853f85180a045cee60ae09659bf5f2eaccedf67490ace96654ef0505fdcd27ef867d0b2f68780a087847a340d57eeae7fbfc972b7a1ed7880191cb88b9e76c9c7c0cc472e26732180808080808080808080808080f856a0fac7cbbb14065869b5224580430971a0216e98a78ef2db9f9baa7af62123f5f6b4f3a0200e08b9fab50def1c8ae0ad44dd6bb2e992b3a7dbed7818daf82440eca808a79190a0fd1887216c9620a64a6e41fa4c345ff856a0600dd1fb01dd454ee579f34adf14158573e9830a7a79faf4d7477a5b7e15d1cbb4f3a020dc68d1fa04172661606a74d732819bb4d8af249a7c6c5d91eb5d17cce6da709190a07406a455df4ca89c7157ce24201690f876a02c8933c959c8670ba40616e739a92e6a211be8d8525929fa9b1f40d03323efcbb853f851808080808080808080a0685c7c2d67d4135c7c31b6ef59f25e693db934ea9968b0c7a1e835fc8ae71f988080808080a0d52ddb4ce2b7dd123ea5788a701bc30089cc51942f64ace7b000cd7c89d8a95580f856a00bce8dfeacbce07a70b90ce5627048422e3bfa665944a1bcd11d8456ca5aac11b4f3a0200e9944f3bfff038388fadb35f0009874823db1fa7ed5fffe6b44ace05bc89f9190a0e8dddbb3f2b316c091707848fa374df856a0ad120a4993a5e5ddadc96299eb3cecd605dbaebf50946df6219d685952c4f470b4f3a020e248d2ae1eefa6f91e6b60926386cdec846024b9c3decbf704b26de67d8938919066ffd2c92d3b521444069cc15043bdd7f856a094aa3b5c3dcdf6e7baf220b040370ae5522f52f87bc38ced3ed95b7e6ac0c0bcb4f3a02018a65f4ebe3f9022e7ca55d51aca34441586ba206e29f3544b43f70089f0c79190fc496abed83b2db7f9f5a574605880e3f8d6a0d1618349e6813f5cfc0ae3b99ad6873d060a114b17346662f891ac210ac837b9b8b3f8b1808080a007ccad3194eaafeb7460acf796fc03d3f47fe4ed7855353702fcfc01da0bf8798080a0dfc0b6993fb99afc1fea1f2353fa6639f79faa2fd26adcf5758936c1c98a451380a0d9e5ea4d5e838fe45f2f0885a9e68244694bb817ebeb923fed8baf8802c4e6d4a0f86f339d1058feebf6a3402d0ce64e02c325f727dd8c9cbf280ea192970b756f80808080a0542f5709895e3c35d1c02c0a8df15b0d46089fbaee4feeb421dd2ce499e3277a8080f876a013885e2135b874cc911fc7d2e634ea5a4609909c77052d7866f632cf30860f90b853f8518080808080a009334c0a25eecf4c9e6407db49c7ad8f72e12552a8e29916850d2c41d62203208080808080808080a0b9cc52b39eaf087d273375174d57ebe5ff72641261492a2c5fe32dad88ab96688080f856a0cc833978e1e833773b84d44e6006e269daf282e398623700b10ff7473be4e8c8b4f3a02097ad7c7175976d0a000bb4a5fcc8188a5f863aeee161317d37d19591f460f59190a0a4ac19dcf51daefa0a947684c72fc5f856a01c7ff598db30daec33600d09269afe7ada647ece3612b702ac5679876061d651b4f3a020c1dced084213c05967ede93e35cf3596b6be5ccb3586fb0552d22a836cd1129190a03410cf24ef75ff527e74e050870b0df855a01348d7ae5fc621432eb0425b0aa7d937061739521d86a841738c8052cb5ecaf4b3f29f3856e897bf71ef4803a78b94b499d27991a5bc479be8a074498ec8c2c835279190a0c4b8687c3305930ebbb6e4739dd4b2f856a07e455536af2128bccc47b352d1a400a7d75e0d1c545cf3258453cb25a4d24794b4f3a020fb25d0e55776100e595a7f879bb8d56aab714d63ee6bd7b93c99e858361b0891908916256fd5b13bc6ee8db13140505e51f855a03601b9d51bf36810e943a1a5cf5fe72e688dae218132306130138b5d42408cfbb3f29f319fe1a7ef2face250842978e4ae1b8789549fa03f518b68d874c399bc3f4591900f094353e6859ed3c3ba95488ddbdb0cf8d6a027314e383f05c19820211f382ab314a1bce529f43a65e1c30c97dded2ab5b489b8b3f8b1a01760bdebf089437225e92799947534f492e7cc4299de7f8182e7eedbca01a49380a066616365197170703d9e6e51f23ce102acdb965634c07e460858966e98879601a07cda752225944feaa452349dabb8d078c44feda7302b9cc376de68fd2e2fa2f9a09042d896f8fcc1590e04c0fb3276d44b86c10e269518de14dac8876a90476bbf80808080808080a00f266e34698dd7c4c44fecae103196ecfad5a6b8b79ff345350c584230dd071280808080f856a0a00d207dccba60799f6fffdbd7ea253543b1afb6f3846e7bfb5af2d01cd56d2bb4f3a0207b9c96cd2abb41891642dd40f3128462990a0cf81a24d90f5a532bda670f5b91909fbddf134523c5efa403914f7c4adcf1f856a0d8310fccc8b094655e94574a74d633e0dac1f65b289b786b145852ecb1fb8729b4f3a02099c1dce788770d78f265b53fe0858691159e741cc1ea35aaa6c60c8c8a1a0291902759c01b70dd3ca22cb610c48acd1a0ef855a09b361790f433c5d6133b1b8997ee3c49ae8cc0e53dd754d3143e40847525414cb3f29f3c079e8d0f6144c4b7d3fe03a79d7b46dff37d735ff6f304107b2acabb8aa29190f0b5c3ad891553ca6d8d4f6fe1946a82f856a00978efd7012105813bd133585ee7304725cc07f634404d57af9b22bed33e14abb4f3a0200b0c3cd38c23984d65c40f90d3ea592a9c5f39fbc7bd05ca24b54b987bcf1f9190a03d2f7fc9f53b8513691b3d5309c704f856a0795c6b220a9ad547c58c5c7f03fa6e1f6e1fa401ad11eac5edbba04ec15b03dab4f3a020c5ef3f9174eda80f0fae1c9a0e61f4c35dca1add27305bb799ce51543c2f309190a0725a463c7dd5eed6b27cdbbedd0112f876a003645975db51b49767714792dc7eb8c0e63d4210ed3b734e0cd0bb80ecfc232db853f85180808080a05bed3de7860170692f1bf4d25991625a3c3e9128b20ca1c16d106a9eb53de25e8080a09fdef45a3102f268a7cdfbc2e5afe2e77a629c3bd30c062af02f9c908fa2ea4f808080808080808080f856a0c6f07d74b36b9b59b2d1d92016aed4fe72b45f5db36473b9ef8c9b8f2bb9eb82b4f3a020bcbb6e3622b85b66b6e65d1440fc8b918b05cfdd8b1b21c9e6c34d49b569929190a05bf4d1c9482130810617277169fa3cf856a0db285553fa88ad42ab1cff6821bbb8972371f6f13cb18e0c9198ead5330dee10b4f3a0202cc07a47058b77aad1518393326f43882b2cb5357b522ba3c0d824fb41331b9190a01fedb4e549efd13f406c152f8250caf856a0fce72e67195d52ebebd190967c18f893759c7061811d1d5f6bcb96223a193b20b4f3a020d698c06198eeae263f6529042ef845acca916a4d3774f20619746293afc8869190a3ea6fa432cf8a57ef404ac5ee8deb32f856a0cceeaf6d578506fab791725a471cb242c68c7b550f9902ef7159f94230144185b4f3a02050f85c51a4cd3c5d0bddaf580cdb6221ea15afb8ad9d6ceb061d8ebafddf169190a037d06f632254d77be16bb3c5f428c3f855a02eb8c9da8a15c67f2404dc0f0e0a0977069586596055375159510ae62710b824b3f29f3945ce35a3eb27996b5c9186a93e3deb0ae27c2bf0a599086ce18380756efa91905b581aeca5e78781efcef4c957a7a14af855a00af169f694a0204c2bbbd4cbb7a7c0c0030c1bbb89585f038bbeba2fc760ab98b3f29f3ca938465fa95c5fdddc58dd3ea55a7ee6d45e4904fb604bcafac894bfd0139190a00da8071a3aeea71737c92f909535b0f856a08e67b7d19bdc0a0947b8a6d0c50a1fdd297b40e08d3c21295d809b0217b42f1bb4f3a0200c06d0de54bebe8a4b99e8440ced39e1ab391fe72bda818d35325e55e73e589190a000912b440f6a5daf60f37b06b4b85af856a0fc87d057d569c9554255a0667ea790ac17cbabf93357ce46cc1f7d866d8cde6cb4f3a0207453907317d2cae3729228861bb611d9de4c023065986284742309dc7e216a9190862a10a5b24a5b5c533d14489b92a54bf855a0f3e0c5b650e2da5def7ac14737330cf78010ed6680a362bde36876cd21fc2863b3f29f20f6d14146d06acabad0bf828bb99ec288c7b98275e506de9958aac9a20e839190a0cd91d0bd7937032c0b20b73decbdd6f8d6a0ccc84d4fb717b937a137bc6794222effb7df967a90077df8bb845abe01eb4705b8b3f8b1a08d8a0281a5d75e401eabf298aa1f5d963377b6131abc59889a367ecef651ce39808080a0ea57938d6f6adecb3fe7da79e1d92bc7d0044854cc369cce111a8b3abcac85bd8080a061a32707b1ec79647c453bd8450533a7da1205d9d0767ecdc5e16d91c6b02fc1a0466a117cd13c96b18818d49859d920201e3917676bcfe88b91e5776a01e79fbb8080808080a0a3371060ecbb55130ca271e208df30204b6397d8e2243aa867aeca33c9e0955a8080f856a0db1ce4e424839fc809bab015def4cc4ebbc7d5e39db93329eeb223425165ccf5b4f3a020e03206ae4972889c137db05f252d811b0bb3ba175f5ba9d2cfac438f1d73da91902ba158587e9bbb709172ef72d8156e0ef8f6a0be11ec205ac98f4a8e06ecbfb6acba323ea00416761e67a04ac21db5edaf9e09b8d3f8d180a0189716521e01ed528796ed4254db20d40e8a2210d8c9e5fb4847a5939ae67d528080a000cf4547bbaf5d1702c1ad0c83706397f148d6e91837ecbfbf211a5d0ed96658a007976471676eb57090fc1bd6f7e5b6acf79592a53f1b2631d4326e66dc6b41e880a07aadb6fc6a101f0278b15319a3e5de0903b051c2ba87a1dc604217315e55ec9780a0c66c6da4a0a9089fe766b11638a898d94e3f2211d01627193e1f104b3f09d3c98080808080a0c2189ebe765aace70627396b64ef0a50a65a03835dbf21400b9d479bd13e408180f855a019f5d07cbc29e6d520561bc52bc3317494a51e2110765e33123ac7e420803bd8b3f29f38d27b068f98b6821d87d414c4b8b8812e48529fc7f2faa886cbea2f1293d89190912df815452ed5a4b8e601c998c5c5dff855a0bbeb99a001e7532012244c5eed05ca277f8677358d5b9df9c21c791935fde666b3f29f3e4b4322748a30d01b3d6998e39e0f99ca5d7e0515ee16dd08927d168d365e919041872f648b51a5ab49a534a0d440f62cf855a06cb49fe7a2e524e2c8c756a42bb380c7e957683477b3e23e45f9e9e87060b49bb3f29f209aaf35dd47af6276675480c471c0705103193b5846bdbd9b34ec2d1f24539190a07721ac7826c585b675bed7394d8028f855a060bd5385a838c68869f49a7aa71d85a8a2cba6b83bd6cd64256efbd2c1c14649b3f29f202825e7ade676cf281d007e594d37954f5afbe2d777d0b9297f35c1836d069190a0ef004560df78f883969dd3626df926f855a0758a094be7201f66baf4903b597a9a8944b0e6e6f0c54c73ea2f3e786eee3646b3f29f3318c04c6d8b9a19d400898199c6072a33dbbff718921e9f51188131b3b7fa9190a010259b8e42c408e6b3d8ff5b6fec57f856a0dd0ebc1e02ce5c39c9793d46bc5dca663ef5276ecf68805d6ce51eb405f7ffc1b4f3a020074a110e2c62f9727e781dbd2ed8376079ebbae9e38d416eb408e7bd5c32869190c5c6f99930f2db94f6afab2d03c387ccf876a03030d5e273742ea2ddb9f1ed780b732dda81dd0659c237d92ac9c870dc8ef404b853f85180808080808080a07162ea81221128d80e0270702b3b4427905eba381e1e1e8a0e3ee26c94699d45808080a091c3563caf8f76d7c44c6b8a291bb148f8c97f2ccf225b62ce6c5b780c54ea278080808080f856a026598322ae014331078ac5c25aef16cec574d858a535de77360f46383025e8c5b4f3a020a478ee1343878f1f6070fd398320f52da2265e8729273b1194ebeac245a1119190720986f93e79524284e3eb69ef459bd8f856a04282f2b6140da10f3cee34d32b98fe8ecad74bb98514ba7275f4ab7efb6034b8b4f3a020b6ab82af7f2a820e23f7771a5bc6c147454ab12cf57444e3afd39ee9eb19139190a0e4cc383be0044f367468b9c5ed02b2f90138a004853709c41624bdfb4c20360d5447aa9e2b5c6da6982f3e872a11791c4cecacb90114f90111a0049632527461eb7a74750258a02a53aafc76fe29ecf6d4372c3d6f733124c14aa0391bb90e7958bccea70c2cc8da6f7e4bf19717eab7fc9cbe8ffb305eefa2a30c8080a0ea916513a029af1f8f2275d17a442d83591e445f529c4a8c3e4069dab35de706808080a0396cb8dd55590620a8ddf80a083cf782c176fd22912c3b6c59e7fc742c83468680a0a0a06218bed9c7ccc69f1fe8adbd5a573cf6096734ccc50e9a7930ad821865cc8080a0a9a02598f858b93d880c08b3d85e1c1f0dd2186ab2d073e4be9da8aca9a2160aa034d83628b645191c694f11a60a4aad830e6f81d8b7196520ced8146426095f07a0aff40ed122791aaee2c940e733552989bb4f817b2ed7b7d84ad696e875d6d7b980f90238a0514f5c0c8944e5976cae88a7863f4e9192dc2186c063d1028f3c6eea8eea48bfb90214f90211a023d9adf2fa34f62694d7ff7358f2ca0f680b752ad4beb33ae88601f9d0321f8aa086f80955897e82ebd6664a386f204722029e7b6ff5b43def9182282e623b249ca0d589608323b008e248fc03f2e8975993d2e44d95f9ef349b1c807035f04f9cbaa082ddafc1df998e4d8b3292699c6e911dc6024249e44d2a4fd48f544c8ca89a45a01dd762f9bdb281cfaea5fd1c1f51c54901f5a3520487517f39e1f3b533b1fc43a00499c4395dfc97cd2230b0ce12727dbd0c7c715dc45be67317060dc9e7ae5734a0cf5572eb5fb9e19b16093752c60323c1377b31c633e0c983fff216cad4fd5787a09d95fd0fee7d134078544b9c3b7754f55ddd92c274d26e75ae39dacc404e6804a0006dd4c3012713034fbac07d7f1599044ac500b348437dc7633bcd6de6cb47afa0baf90fea9ff8b8f43af00cf4c4ed649cea4e58c898c53559aed3c1a11728350aa0c9c40fad920775e50fc93330819dd2874a61100ecdc1c128d24897977c482d0aa0f5712389f9148a985ceeb39279cce705eefda516376d464fb48a07feeb1b9c07a029b622addb444e4b3a4d46bc262183870ae050584a77962912c8dbfa074383b8a0c820ae8572268e8915c15c2ce663f0516331caa47edc2f015f9586aafb6cec06a01cc43d708f6cb301d65b90e6bc827280624dffa8dfefd36914ecac36b227d0e4a04ef040783eb298ceed76abe55dd480d4dbf8068ce012e2eaddcce6ffb8d9035780f856a0a44881d27be8f0727269ffa3dffc84f9e81855b9da1797f77e68ecb9789fcecfb4f3a0209eac2d44fd38e83247bde6107d52d413757b56e1ee828bb5e4856cbd7d837c919074da540ade4dc522afd5eaa85768d23cf856a05c4e13acda5e0f876687f2968a2c204aaf13eb0f3643c30e20ef7547d1933636b4f3a020fffc970b03556eb993d3a73d137edacb47c53c6ab7a3ba096bc0335fcb4cae919058d7c42d5d64feb122ea4dd0ccdfde86f855a06cc468a8dee37e84433cce4592cec44eeab92ac6ac16b771305a30b0b0cf5cf8b3f29f36de13920a777b43d41f874472b69fb8bddc7a46ec11c746cd747c3db77d8a91903e3be1a0057af3dd7388d6d672640c21f855a0bbd415b25ca9fd96ea4194e019bb42398dd80a95cf49a8c8e2ceb9c7234e13b4b3f29f3edcd793d6f636dc1162ebdc53273d911053562076d7bd3945ecbd3e9c82af9190244aa1de7e38b135c70b51b95b1e1023f856a0654bc4cd74dd4edac8b3db933744ed090efc59073ead2c3421f0b1853c3784c2b4f3a02013bbae4ceb6ed0bcfaf9cbef6fb02586babb23f8932787d8c975914da196c19190d0dab1ba79d63a35322601dd3e08decdf856a0182cdeba4a5d84bf62ad70adcec3ac2eb6a3a37631348190f0fd702248a07be7b4f3a03272747956ae87ff7a2a4b58a3f98859907a511fc3c9e4cab430fd8dfbd504ad9190a0909e96e631750a5cf5995b65783a97f855a0412605c025a76e01ebd84c85ad2697a41a7839901e8b0d25366f24732a355d84b3f29f3f3d85ecc359bfe08726ae3d9b2e22e00e4fb874b1f5067f87bd5b057b439f9190e242316b567a64f5da28cda4293809fbf855a06da23c373fdf4c496895dcae617c7dff19085e33f09e357842d7588024fc48d2b3f29f388e3eabc485e180f9c1af38835f5b29ec5efebdfab7d24311bbf69d2a971e9190a0ccb37891fbdff7cfafa67e7f399d97f856a03c5c54a27633de03c524bdc3f4e01968ac323c928a815790a4a6d6b47cef956fb4f3a020c5e616d43b2354cb5a91209c6a7305e4360d069e107336dbf435d9c7b387fe9190a08024faefbf2a5035ae74b95102b4fdf855a0e114df924af4eccdf78618f1c359129e413f1c90c36f72265d7ec57ad744bf93b3f29f37a5bed6b0adf940ef2b39dabc3056bf711edd63fb8832eaf2f4ba13b00f449190a07bd83ff79f6a511f019c8324c998f4f855a06078e36cd63de575dd25cb2cf233827a851a8ac91b7c10e1e06a8c6f18611d47b3f29f38e7709d461d463ac4823e376c52d7d0e086f61f9fdea32473a9ce6336666c9190cd3c108a2a51a7e911b14f72dc4613a8f855a08a17f861d2941b9537bd9a87fbd76fe2f30326163e4ae42f693825ba2e0aa2d5b3f29f332c8f4f4fdf84b68e1d95d020ef84ccd8858431b0bea92ab48dab6924d4829190a0908d0110c82854ce0750473b82a21af856a0a5d585f033519cdaaa0a2cb095be0b75229e455abb5ba854a8af021b0c90aabbb4f3a020a1dcfc5195002aa8f368287abf5f8bc81aede815d301f207a7b37e948a6c179190c198779b6d22926fd46fcceb567d8198f876a03a269a3c32db88054eeb3acf03aa5ab89a8c9bf93cac53e050acd7eb1b4de10bb853f85180808080a0bf3cf6789998ca285eb774ab6bfa9c975936564b2192fa3106df65d3d9c9b8b7808080808080808080a032c1caab6c4ff4c01301ac8aa40806d617379214d293fc0e888e190c50ed90f68080f856a09299de2d468d5d7928212d5d67ea356ac9dd0bcd055a1df14138b748e0cd2fc0b4f3a0200b6cee850a00880fc62ac6279d892cba4f489643ef3daa9d913266e07ff47e9190a0ef815c27b4e00bcfaef644a87cebf6f855a0952bb5f66abe416970ba8bc15b5a6fe62c2723f221f9099b2a7d876cf6d34124b3f29f3c950d4d1d0c715c575369acda455956af50c2ba36c3dbc376e5e00e8a392f9190a0e789c18a5761ad66b2538bce24e76af876a02fcd0083007ccd84370833ba4041876ca47ae2e7df3081b568f8ee7274f99276b853f851808080a017a034649af716fd9a46a21078e60799d2f9658cf35dfab8979d5c4631d961f78080808080808080808080a00e198a3c519117f29f4d3480c5e61e6ed7e2476567830dfa6faf663b3de7009b80f876a0ab1ced1be7482d10563fa0ac4114f7276fa1dda5c00ce521aec74afc8f517cbab853f85180808080808080a0e8ab6855e330ba6b52b3495ab2d6acdeae27daf2a61a2c56e76e1d75bc4d4d3ca0b76272d1fc4b6df3c24c95460bd0de85e7152aebb1ebf2c24152ecc0e32fb8b88080808080808080f855a0bd24b1795b9e3fc393c5955c3f16354b2b9c38cc8f9278d5bbf2f1b9722c3d6bb3f29f3cb3e36acfbb067096c27bf680e6258e991ad64da171ada6a35ca46a2a7d279190f2a4b18eacd82be83c1a1fed262b37e0f856a04b5006baf9dc32821f41ffba921e16506aed63e6aff2bc1b1b376b1f564d61c3b4f3a02017e1c952cd59537681f4be6139e0302ca29e4fa74ecf64e8081011c97503539190a00c172d5d18a9329dae0d4489339c87f856a0ad48c6523d698e833cfae8f8aa1fc2b1d93c44b45c0b211d5a8c74b85325bd09b4f3a0200fd7bbe5bf5ed33f8b2dd4a8557523597eb1deb86fa5ea1a07cfc14c80660e9190a30ab1b435c557c082b485c1f409805ef876a0cd6df92cbd16bb23cd5e370388d1b79c4cb211a44f87691ac802d689d7f6f40bb853f8518080a01d1d33b67918d16b94a0fb8e5982efda404b42fffead0ccaf62b1bf0da0790db8080a0694adffdfaee7bf7dc633ce5133da351cde602ed1e456781a6c68494de7be3d18080808080808080808080f90116a08210ea9f4c4fb5556290aa731d61998cd67027b11b6f6f167593f43a98bc8f9fb8f3f8f1a0dcd9ec060d81a3dbea62b7010697ed4e0e2faa85c6402a92f0498ef84b7c2c2aa09a3ef7761d0b903c96d73d4bab5d27e1e9d5a08784c6f1fcddfa608760928d2980a0a13d663af660ab641efcccfbe7ffd5dbf67019845580faad4cbede0ff61701b880a00d900c1dc410323f8f27d3132ca6eee9f1225b28da9b1fae4b8afeaa29b9bfa8a058a6f0661f6f3839d27112ddf86dfee47bfdb7d1d89891f7c4fea9532b149d35808080a0c9851ae678278c9d79a8d748fa906932985c4d7aa15c3be32c130a9d2d715f0880808080a0f931247472c96d26aba2aace12a9e03edb01543746add907189d35fbc668f82580f856a0eebf7047aa5be9758b113a329398f56904ea148a22edce37f50b572e462b2ebeb4f3a0209a90ca74e49312ed4cdab0dbc74c0ce085461d511b0ec25ddf242f75bfabdd9190b95603ca47322a5ccb7bf08583c88b11f856a0165b4628ba2b55c359c01e096b1a23bcd1c3f38eafe4f23580df05d151cd66cab4f3a020bdb88fb9320df4ae6f27df2a1c58edeaecfc83654d083202de73a8edc1fd7a9190a0c046bd23c852f58e741f3ce6d975cef855a022fc46ee85dca27133ab94b9dab7aeba106220f90217ffca1dafdd83072af61ab3f29f31f22ff575793aeea2b96e37597648de75e90cda64cc4b68882736f9fc6d1f919061f325b78e91cf5dd679f69a9ac6e2fcf856a0e03c879e23f9c5f07c750f984e5b442018226fa76864b07726688dbffc158dcdb4f3a020df72ebc7815d6f739ab9d74676a5a481310649986bb9bee1f8c3f15116807f9190a0dfa4052752626266c681eb9104436df856a003244efb51db9855c0964cbce4bddd7d2091b833968e67cee6ed2015208c537ab4f3a0205e25317fb1ccb6101951194e973fa61eb0a5ec0d0352fd69bd953a9875b8ad9190fccb639e86aafd938118d1ceb8973781f856a086b92955a5dcf11d1d41f1c7484bd98b51323eb3014ee430e1a9ff091c316b76b4f3a020763afb94a20e9411e8574d134b12e51d2ea4f2fd7ef087c202b1b7271df1f89190a0e62b6a13b71e4afbf5008faebaef01f855a05b5e5b4f004c4a48f9282e213bdf81639763ad211c0a934201c0d5b4d4b454f3b3f29f208f6a170b663ecd4d94734504263968feda83af7685541cf569047924e0389190f2a48dd6953c1ecd0ec19b1e322bdacff856a035ddfefe6a302b96361e7bd9cf4146b8d3f588d7e98a67fb54796a356943ca4db4f3a020256ff50502d1f4b1d1fe8052e7565bff0501c4d5bf2e2804f3e0d9816ae3709190a0afa01d8278b8ef60c20f7302f1e2ecf855a0838e37ecc3075c29565a8f1e20ce8a4315845db9cb0881340fb6370d162d3e94b3f29f3a04d0986cdbf5d4544b5020257671e0150477027621835b0e6f3f21617da591908d916edef76afb17b1ab242396620976f8b6a086354c0b1aa8b9f33fc47222ee2f4fb312ec1e970a9678b6309e8858762f3146b893f891808080808080808080a0de6340047cb9ede82bf2a6202ae60d894124335aedc750972ef2ec0403c0c2b38080a0a4e5c3b7098b57c72b991f90a5abfb9b975ff3681d5f3c821f4b2ec4e652c628a0c508b8465eeedc2dc7267c1463e30383a0a468ab48c786b72b98341b1581732680a096713de783bc6ac79cd7cd1615abebc41d335713eb814f08a5296b5c1a4a84c380f855a01e19437722233bf6fce9f3cd3d1c5f64d9866d9cd5d8d0eeb2d8d5e38534f6d4b3f29f35e2ed2227948a427d78d55a95089b07c392d4431bf56bc604891a7c21566a9190a0fb475982f17af6315435df2a900817f855a0246826d6f44560aaed00e8182a495f04fe72e32103d25876dfd78d0cad427088b3f29f30fb2dbb1df4d6da33389200ea98b7d5291de41d807f1bfefe3677deda7af49190f38c1b2c0e36831bd56ef99840675820f856a0586c29bf23f757845be4c490123634aba6e2706cee1998f6d96a4e4370bc405ab4f3a020538c1601966a6e8c3d7da035c4c83fe7b4b4981a6185399baa4cb73d1a38719190a049bf6045bc86ce6eb7e44a2fcc32f8f855a0d2d380017d8a3c16cb551a5fae345c3c3811339bbedb4d84b09f4db82be1d5eab3f29f31dcf21ffc260760a7a8fc97e57c3a475652b8127e4f215d2a3c94de6ac6f79190a0f786b7a78ad13d4040721be01f3616f856a0fdd9c7beb7f85a981f544a8560e83e900fef08e9a8768bfefc8ce9ef3cef5326b4f3a020a259daee149f0ee1f61a95346cafca2d11098dfeb71b5bfce9408a4ea06b0b9190a0dfc2605618cc0c658c6f5a04e911a7f856a0c1e05b8c9bdfeb9373d09c5f11a2dd2d744a3475a61cd44ecf89e80fef06d825b4f3a020a8f7710228bef9fa8a280ba1075ae7c2a644b0abc8cd68cd8e30ed5efe8df49190964c11d5b4853736f40a0d86123682edf856a0209a136e7a8dda8c3a35b6f5669a55f138460fef8f41f56e42ea9deb33121ccbb4f3a0204160e75b6e1ff6108570853fc7aa9811e22090c55642443e3b57871e3ca66291908a98f67bb79f3d0f68708d47777cdb65f856a002f9dff021023e42ffece3f4c9334bac397d8b0df5e6c239fded497eab253f19b4f3a020adb8dc4ef7be68b4bdb5c70691b0f547c2f6cde3aca2334d525888c912bea49190288f0a2bda324077db6625ee81e03bf4f876a0007127f398cda07396c650856033a313d8922d832a80b48af317d1dd1d29fc37b853f85180808080808080808080a0ab520b3e94949ca7420d05295d10cc92948bd7aa47fa281d6685e0b56435d2a98080a045ec8b42c484a3a615e7f2c1f29de223676d01ff44283f604bfa193047687b71808080f876a080c2c66f07023ebeb01e8eb1604c27ca59e5ffa5dad296ced7a6259f963ab009b853f851a08766d42606366b97e2ac6f55528f54edc16a016725d3d3cdeba7eb19ecaa959780808080808080a079a76d38ad2a0012b0cfcc4e1b201510f37abb5c61e6effeb4ab929f002d438f8080808080808080f856a0ee7986d9651898a13bd4959a0805f32d8df01881bc471875da51b5ce49da4c05b4f3a020efb47b0bde6fd52717884a917372ea487b4e35cd6fa779f084ad9eec8ced92919086430ef9a6cf924de5eb16d96e406828f856a0c2848e6e65983f215390515d4ae946779ad17ecf3ecd75e0da0ecc5fc58e78cab4f3a020ba3148f24bc8515d4f72935b3db036b59e44d7d176fe8bb108546433b8a654919081b254cf536da6e20f9ce5fb4c33d10bf90138a0997d1ec52b4c24fecca2abd749368a5b8933ce1c9a093c8c4a2806d8bac9c307b90114f90111a07db488e8cfabe2f9717abc3471bbb0b1baf1f8df43cab83c09aa7c5a3bdca8d9a0025b9c0a3010bb99ce2d5c6160d347d9634ac9511db956771298e60e3f241919a0c930de9d38c47bbabb68b95563d363f9c605b7445e8407dea3dc4a11cdc407dd808080a01bc3ede86d8d639427bcae0ee9cf4fdc8269b1834fec1a5470bf6d61dec6bd0180a0d9e65fd4c7ff6b877d8fdd0dce1c14c8ea1b7bb021b3d2a488f4c2a0ff7054c280a0078cbabf1e608329d387a7d9ae3f666e32d31ece03e021b7e8c16794167b882e80a0e6731a0ea86657baf528607e72b1ea83052f9162a580fd1180304d881085a1308080a006113c3ae43309fc4b1a03bfbb729502ed93d7d31b3d90c019fc956a51a2941a80f855a055f291a740cc547fe69e1f0e07db384a5e655ab1a3a89c727e4a0eb0ff55ccdbb3f29f34e3ea25517c2f7582e8a46aa292d7008c4dea6017b0e18414bacb56e4e09f9190acdc1e909afec30cdf0df4d28ff14b85f855a0ec438b9f26018dd5e645a911c09772707ac9862c48c17eaf037fc16146cae63fb3f29f37cc096298e6679758edee8dcce9a9c02b086813027fe78ff11ea7f30ccfc09190a0746a04ba771a89fe4d9b42624e6509f856a03df35ac4bc698b7013facc83a82ea0e525794b345927ce476beaec4a1525080fb4f3a0207e4ae8a96ea4b29e514bc5ecf10a1d9664daf950a1b277f7157ac233151d079190e43e84d89136fa20d140f4b095887e64f856a02e133b64986fd0fa7b35b2a9915c7f650886af765e233cf34214aa6117fbe6e0b4f3a020cc624139201ed80cef9684b054ace3b4e8dc49c81e62a17896affd3f5efb899190a0c54daf8d6fa0dd485ea29064438501f856a0628980afdc4047ce89688e1a807d3fac7835ca88da1b2cbfec494a7a62003d02b4f3a0208f4367f8e4caaca8e04745c3ba83740a0dff1afffd4519089b67fcb70c679c9190a02a5e024f2931802ae83885361421dbf855a032854656181ee5e33a9019f6a49f575c8a1e8027647b45c6038c365f1346d66bb3f29f3bdf41bc8297b94d33c3071b2e9aea36e9dc0baf0fb46517f1ced8c12b142c9190a0f29679c2cd05fa069570d5d3e6982af855a07d4f8ef2681b37ac04392c056961cbbe2794e7828f3dbd0750ba4e8bfaaae88cb3f29f3ceae4862bd53a46df2f2d1cffc5a8b975fcc2672d1abe84fe7da70aa81e419190cf49d2c106ab811c498919a520280628f90116a0cd2cec675736425bbb3fd37bf3dc0c299e8f4cd0231a93d136594b8386cf8609b8f3f8f180a0c86bdab224d904c98f72340512473cc70e1cde3d76b965f9551e2b53c16343cb80a091b7e79d6e72ac21ffe33de23b3f713019873f051996f03cfadc5e0daf29373580a012b3a5e27f1a627ded36fe42195bfd12052daf50413fa0cc64ced9c5ab4acdc98080808080a05244aeaeed7c115c656baff2e22737c800121cc1dd6adee2e963382d48d8fb77a0acc3faac9e76a4e2157344cf8f7aea08abfb9f0910ea4f32d43299d0443ffa5980a0da0990aa361aa1653b3cb5a9bf4eef6f01fce9dc47770c495696ca0d6ee5b355a0fe2f2871d1376fd701d4a5cb3148af0ef580c479602989667fbba6e2dba45ef580f896a0007ed198b150dcc4c083e213d26b8d042898a2f7022d86cec82cb367cba36a49b873f87180808080a08d3f4bc8b9096bfb078ad653064a745019c7ff398ce8fae42892f82a7ad70f5e80808080a08eff1bab17a52c2b834b7acc8996b14c27ed7ac8d091b6d68d29f9aed48d09d680808080a02080c51c3174571459f60853580881aa2a9cbfffed090a8f3bc6511857c5db8b8080f855a05f05de2d433047d79bed14992bd0bcf4e8d0cdf65cd7f3388901b68a4fba495db3f29f34dba6013bc35481f4ea800c88ec181e866a205bba56cfb8ef21f32a78b8eb919022718053346cb3c2d846138955328b10f855a036292961a97ec37ea7f74cc1d649d878c3d9ceca3c48aef76c9fc518aa6a3bf5b3f29f3c1c29994abb6728f6ca568e0e7a9fcd7d1b1a8a7db86633a7a11bcfe82ca7919019dea2fc145df483439274e0162c7726f876a006b37fc0f5218c277adbbc2a12929977b7a4958ff362048ef6893a1ac5a3b21ab853f85180808080808080a0d63b63cbb8bb0ba87fa3fa14dc758292ecff6f4550001f7d548e91acd1667ee98080a032e95a1fdec25fae5db541eebd1e3980bc63f2ff6fe96298d4025749b8c727f8808080808080f855a0b38a911b397a5a4d76ba750d7991002b33fb76355f30a03ba54330d419a813bbb3f29f39ab0c0e0584297b1bb640726e34ad53f4d92f11f246af548d33511247cdf99190a01f3d47903713072089c5915cd17c3ff856a0a9a09ac4bb7e4be1105e32cd0b2953dc5674f98444350089c10fbbd3e21277efb4f3a0206317b5a1ac3cab1437feb39af99c4de1c74dd7b7561bd9a2469ea034faee219190a0390cff91733550dd3868ff9926aa8cf856a03d845b179068319e1c2b18417a7d292c1598a1fc7ff76995bdf62060d604ed85b4f3a0202eb39435e361eed58e3bd44aed20aa02b852990c17eb60cdf233deab3fdb9091909634e6e6cb01dd639fb2a24659cb9577f856a050c7b4c34c6f0b8b6536cc41ffb085a392e6c3640094bc4dc5ccf0f063648c79b4f3a0201d6456d7691f16ae5a6db2ed38f45566875cadc4d14696df3f9f580e898a359190a05fe8b6fb1d07a8584a98d49c266b95f856a0decc3bf537604389a2b68b888d78cf2b993dc2825fbdd91af0ec04584da0a20ab4f3a0209b859d6d942fa370c12dd2938406eb3700c810b2775923924cb7a8f1813c3d9190a0e29f33de69290fddaa983777ade6aef856a0783296e8e0a5785410a4d4d6d9f90ed610a1b179def0ce3a92cfb4e9d4a809fab4f3a0205d2e273ab2e5c9c0f9ae7a71f05246a46295733745951627c008a92ae0024b9190a0c6ed9486e9137802d0acdcd9a04992f856a0a7dff3aa298a62adb85491a97a9eee8e9f8dcb060cff685183bf162733673e59b4f3a02041556e16474fabd5271f544e08864a4cefe31084f437d744f542bd2dd160959190a08e8698d162f60c1c9cfe0d6c73b11af856a0d78fdb96b36398000b81bd80876197a9de8f15fbcb580fc79266d9ca9678e2c0b4f3a020eb00cc36aedf6e1cb35f0bfbeb6294b303021a86f7a0548ff2f7885a7d50009190c17649b2e82327319337e0e2fc4f85b3f8d6a0f199c0433c25bd26e81853d90b8d39ab3a13f9c8d9b614b6509bdbea119c3704b8b3f8b180a08251ca9f60edc6a3a9b7118c3a0a072585dc626def95b6c905b8231de6b6c075808080a0c8064ca792b4314403679211355d6cec1262278be142501695482556ca93ea868080a0a9fae9835694d263193f82d2997d3278d135f261be4f3f0fc58cb44da8435f73808080a02472f0a4bfbced328ec356be14db8b5feca85331619aa797a6fb41ffc995b7c880a02afbd8ae5d5ee744cfc352e2e31da1cbdc68f3a8b0f86e0aa6057675ed7c4de38080f876a078d1541df4c2cb0d8fd0ffaf1100c794f7c0cf4e4fa02caff4ef9e1dc86340fab853f8518080a02614a52440ed95cf875d74f2a8f67014c48c7c27ecccad33f9be0197fdad5d198080808080a02a502a104f24f1c190f23c447c4bd7d9d27bda878e8e65a8bd40d6f2dd9713278080808080808080f856a0cdd83d57fdf54c040f9e591e1192bd5712ebeb9ab05f552747cd96053743acdeb4f3a0200e6be36938a5f9d05c51c1c9123a3447b9a9b2d70886fe57e8dacc1adea81491902536383e0a0966a2f8af4a6e9a1c2c11f856a0afbae8f451a5ab19f6fbe5622f51123c40658b74a9217ae482943ca19eb279aab4f3a0209ce4be6565a22bcc6d598a0ca3d906eecb4f9c34cffc3c154670892a5190c99190aa3c467d6b6a7a2353fc3810e4b16926f876a0dd0d09879bb2b85aebd9e8cedba75ceabda5e4c90530c0c6099a739cf8434dd7b853f85180a0649000a6130cd2cb69d32b6780725cd451f4d617f5a74218047b507be2e6b6448080808080808080808080a0366da59cdd2fd25d8e66f9bdd6de89f25ef0dcf98aa0173fe79dea4be9c17d68808080f8d6a0193f81337883b6711a531d576d101be7d51bff8cea5c0386ddf02fa1c9365740b8b3f8b1a02ba0d9e8d7c5574daf657b5da992a26d3740ad325df33df2bcd175aeda38c9678080808080a07c39b7d731f3fcb33b261fe46341193a232e9390a17b7e5610fe420932e4ebf9808080808080a022b160e86b30748fb37c258928aec860119a84864bee8c8ed21e9a2ccaa243c6a05c84ca75e6c6603aef1224db6077ea05720c2cb200c2ca0f3d7b92578a3beb59a0842a25a5c233090004e86efa120df9648d0ba37b3409c43733b7f98b6cbd1b0a80f876a00427a68d7e9e6aa9b6374d47f131bd3925a68a37f6ecbe465b30c649f45ecd5bb853f8518080808080808080a0e5fc3c588fc5db734370f8bab118cc3095d1404e2db420dfb96f196e2dc31490a007a4e976b9115a031956cb6fb02b889334fbc1f55ee0b2454bcd3f95710c7c1780808080808080f855a0b0097f17e36bb378f50a4a3dd29ee5fb4365e83e55bcbe3e8978edf25bed2361b3f29f20a179d2db7e204ed511e5fcc45b8b1798c54aafe44ef172c09b931324568f9190a0120c0d46f7b31005f4c26ba60d9965f876a0da8ba3ceb988da569f04466b58a7d32795ca6f84031c026ecae33010f94769b0b853f85180808080a01af1a0bde7120c48481f13864f5d81ca0d6831423b03821756c909f77fb35dd78080808080a0682c8b621bd2493af7ca2e0ee08f1ae03e57761842cde588d44beca44a48f7fb808080808080f856a0a82b19665b47935ca185a484fd3b34a67f15c3d7fe311dcb302345c4beb8515ab4f3a020a6dd631e4908d1edc583f8866d35407b2e82ff543f1b8eb523e64f245b2aa59190a00ad202c0c7ab61afd556025f709b1af855a0836c99fec866d910cb492939c5e033d654f740666545243023d11053d4a1d822b3f29f30e28fdd35990e27346501108c26cdbd824a6c2ca47d217bf5aaaa5d6a95f49190a030fd8e6a631b69985a836a0d407e21f845a02f483a2212f460f31b939b16dbd37cc3e3aef1ecb3286f0b58c0a9ba20bf6264a3e21da02861d0039cf950b510f0f6ac4be8f0c4f5f5b406bc827b037f0e9cc4c9a444c8f856a08962e14b60e669feaa5d12d3d85e8338e799eacdf4670b717e27a2da0cd6653ab4f3a02075a85e3c28a07c13e8ebe73a3329afe79644150ddbc4915510b491488237f691901d5587a122e7b80e75b6cce85b3fe621f876a09ed614bcd83aa7822221dd00d91cf94f3d3bfc596a1da30539ebbc939a15262ab853f851808080a0511a726d85fd63c15268ff45759ae6e48a8b066f4d73ce8b9a5bd2a405d267d880808080808080a0bf037a6ac4d6649ea6d2ac159f441489ab682beb6380cf00260da50dcf7a4d658080808080f896a02d5ec1671e7579f58ebba6f754605d29de0e0c86a4acc4d0f6d907eefdc428bbb873f87180808080a08a8f541b5eed3db7f34e469bb74bc173fd951c3e63e773d0b9914716ed33841880a0da24d83ff251743716406bc3ff3911854dd39e5cb1668be314fdd84cb72709098080808080808080a04fb8e5703ced053cabb71ff1e05fc8febe033f384129eee2ff26b70baccacac080f876a0034c0abc7c206dbdada02b24c26a563de0159d2bb03be0bcafdce3818b8bd714b853f85180808080808080808080a05fb6b885c57d7df64ddece6a499e5fcd438df1fff2d1c1bbe5d109a02e33fff080a0f708267c95d3ede35b8c210c4572d25954feb1b86e7830440779aad9db7b836080808080f856a0289c0bea08dca40dcf42a5a9c138004c193ff00da9015cfe385e0c830dbd05ecb4f3a020db69fafa0b845b63a7f55ed4f34ca80fefff1b9aed4c96209df0aa5e38d84f91903502fccd078bd1ff0321ae88f8ae6521f856a0e29bf9c46d57600441de803500f0342dd1c1cdbc4b5bafe86421919cea020a33b4f3a020e5c292c24848e682aa111c569a60b3f29daf5a1ecafb6535b4c566a97e82d59190a0e649954342a814332c4e14a90ceaf9f855a0d1c538862786eaac8a5398c1025a1dae5d220d4ac1bffe1e54111168735f0256b3f29f2047936f71a787b183594df83c05a6792033479c6a98536a1d2330567a60d39190a03e4611dc10fce14060722e79618e53f8f6a0cbbd91219a88d625a2ffd719b442fd6fe3956d18dd3b9b7a1be3cade2e7afc84b8d3f8d1808080808080a02c74e820cded93b37bb445e2b379dee2cdd1acd347da0e07dc4fd097f73aaeef808080a0e4d46454e6c8f24ec883efd33c1a9a8ecccc337986bfe28ec27951ab069226cea0d367385c7652afbebf775dcbf52049070a61492525835d3e767705de6cff49c3a038b4b768b302e9bd71d25d8886a1c7c678dc604c645a056940b70aa086683e6c80a0f80fcdaddc6c65555f2770dd0e59263da1722cbf6fc64fa68fda4a36c09e9023a0dff4072ee1b2a876bd4c505eacb512e06f29893d736261d00aa3ff56abe267f680f855a089d7a8027c385c45b37c3618740baafecd29a3e76233a81dcc83243e8050a45db3f29f3bf5ae170ba85b590c7d7eabaf4c1111ec6bdc9e51d8b2885c8195247a3ce99190cf92627f5433e7cbf8cc8fc9014b3258f856a04104688801b59418a111128a80dc3c8db3835d21aaf36d99afebc524bdefd072b4f3a0209876fff482174c409f697ba972168eb1a0a77fb3606a5ad82e73025c0a7ef99190a0e51279365d382a7da92a120c1f1641f856a0dee17360f32b96db8fca55e2cd0f31c1d512b502a9ac5eb0b287161994621856b4f3a020957709912fc41cfc9f4d0e1f06fddddcc918c3dce9165587c6337d5d5998f391906a73604e061e37ce722e1c117dd9ec8ff8d6a04a18a3b2fb83af7059804bae2f955e7a0f165a520ec9b01339dd3aeb425ea854b8b3f8b180808080a0ad48790e7e4f7c5fa4a8d28679688d72829aa55aaaee5270251e67c71895dceca03ece79f6f7eabfbbfa1dda8471eb84164e62c727d2770119b4bd0bffe1ca4a08a031351d34af011c2882e89b92bd009816071bd40907513502b068b62193c4614ea02b25e349c54dfa3a83fed3f1320059c27094be3931ebd34c8ce932668e7e3975808080a064e53231c4ec72f0518f1301ad55cb2ba707dfd494a2a80d3356a64f84927ac88080808080f856a0037f87bba25f82ce240afb9d85a46802237bce7bd1c074c83023b27226eceaebb4f3a02032a461fe54a6143d269d3c925687c99ef06a08bbaedd650b72e08fb74aaeeb9190d729c7457ec24ff6bc60f95752186359")).withContractIndex(contract_cab26, ByteArrayWrapper.wrap(Hex.decode("0d84c716d0160e91ba7dddfdadbb5389169d0112be9aa2fb540b3b3137c57768")), ByteArrayWrapper.wrap(Hex.decode("844358ea1e0368c7d37fe232a61687dde2254d3e4c99c797993c2b95fe835bab")), InternalVmType.FVM).withAvmEnabled().build().bc;
    // ensure the contract does not exist before the import
    AionAddress contract_685a1 = AddressUtils.wrapAddress("a081848ba2854cb906d9c14892cb0f8d08da46b57cd44e47e6cb273e9a4685a1");
    assertThat(blockchain.getRepository().getAccountState(contract_685a1)).isNull();
    // import block
    Pair<ImportResult, AionBlockSummary> results = blockchain.tryToConnectAndFetchSummary(blockToImport);
    assertThat(results.getLeft()).isEqualTo(ImportResult.IMPORTED_BEST);
    // check that the new account state exists
    AccountState account_685a1 = blockchain.getRepository().getAccountState(contract_685a1);
    assertThat(account_685a1).isNotNull();
    byte[] storedCodeHash = account_685a1.getCodeHash();
    assertThat(storedCodeHash).isEqualTo(Hex.decode("4d93ab5e6fefb5b0fe77159447121edd788acb58b7ef48c3f4ab8fae417159f9"));
    // check that the contract index was correctly updated
    ContractInformation ci = blockchain.getRepository().getIndexedContractInformation(contract_685a1);
    assertThat(ci.getVmUsed(storedCodeHash)).isEqualTo(InternalVmType.FVM);
    assertThat(ci.getInceptionBlocks(storedCodeHash)).contains(blockToImport.getHashWrapper());
    // collect the consensus information from the block & receipt.
    AionBlockSummary blockSummary = results.getRight();
    // check the receipt
    AionTxReceipt receipt = blockSummary.getSummaries().get(0).getReceipt();
    assertThat(receipt.isSuccessful()).isTrue();
    assertThat(receipt.getEnergyUsed()).isEqualTo(1_170_797L);
    assertThat(receipt.getPostTxState()).isEqualTo(Hex.decode("3acbd8e5b0f259e1bd292a4b688cabe9f91c67a51c3e14d893a488349c4f6859"));
    assertThat(receipt.getReceiptTrieEncoded()).isEqualTo(Hex.decode("f9025aa03acbd8e5b0f259e1bd292a4b688cabe9f91c67a51c3e14d893a488349c4f6859b9010000004000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000040000000000020000004000000000000040000000000000000000000004000000000080000000000000000040000100000000000000000000000000000000000002000000000000000000000000000000800000000000000000000000000000000000000000000000000002000000000000000200000000001000000004800000000000000000000000000000000000000000000000080000000000040000000400000000000f90133f887a0a081848ba2854cb906d9c14892cb0f8d08da46b57cd44e47e6cb273e9a4685a1f863a07f0c55adb7f69e3decf3ca20f9a2367b205d728e6905eea6c4fb6f3934f842cca000000000000000000000000000000000000000000010dfde374787bc6e000000a0a000356e7deb04eb8ccfd2bcc756c6159762edc0512760387e2ab5413587443e80f8a8a0a0d270e7759e8fc020df5f1352bf4d329342c1bcdfe9297ef594fa352c7cab26f884a09096ccaf3bc136981b8a043d4e5ef1396a340697147a05ff0597f635003acc00a0a081848ba2854cb906d9c14892cb0f8d08da46b57cd44e47e6cb273e9a4685a1a087c6410c4c8253a24871535e38b61ccf76bfc709cbfb34b3a5a65be94a2d84a6a0a081848ba2854cb906d9c14892cb0f8d08da46b57cd44e47e6cb273e9a4685a180"));
    byte[] stateRoot = blockSummary.getBlock().getStateRoot();
    byte[] blockReceiptsRoot = blockSummary.getBlock().getReceiptsRoot();
    // verify the consensus information.
    String expectedRoot = "a97680f42d7bbb8e175981e9dd847967427edfc8c5279475b70ca131680d5e99";
    String expectedReceiptsRoot = "2b229b5a2c86702495ee53c85cd34a85a8e0746239b947fe4c9d64fc8dd83070";
    assertThat(stateRoot).isEqualTo(Hex.decode(expectedRoot));
    assertThat(blockReceiptsRoot).isEqualTo(Hex.decode(expectedReceiptsRoot));
    // checking repository state and total difficulty
    assertThat(blockchain.getRepository().getRoot()).isEqualTo(Hex.decode(expectedRoot));
    assertThat(blockchain.getTotalDifficulty()).isEqualTo(expectedTotalDifficultyAfterImport);
}
Also used : AionAddress(org.aion.types.AionAddress) ImportResult(org.aion.zero.impl.core.ImportResult) Builder(org.aion.zero.impl.blockchain.StandaloneBlockchain.Builder) StandaloneBlockchain(org.aion.zero.impl.blockchain.StandaloneBlockchain) AccountState(org.aion.base.AccountState) ContractInformation(org.aion.zero.impl.db.ContractInformation) AionBlockSummary(org.aion.zero.impl.types.AionBlockSummary) Block(org.aion.zero.impl.types.Block) BigInteger(java.math.BigInteger) AionTxReceipt(org.aion.base.AionTxReceipt) Test(org.junit.Test)

Aggregations

StandaloneBlockchain (org.aion.zero.impl.blockchain.StandaloneBlockchain)28 Test (org.junit.Test)28 BigInteger (java.math.BigInteger)23 ImportResult (org.aion.zero.impl.core.ImportResult)22 Block (org.aion.zero.impl.types.Block)19 AionTxReceipt (org.aion.base.AionTxReceipt)15 AionBlockSummary (org.aion.zero.impl.types.AionBlockSummary)15 AionAddress (org.aion.types.AionAddress)14 Builder (org.aion.zero.impl.blockchain.StandaloneBlockchain.Builder)14 AionTransaction (org.aion.base.AionTransaction)12 ECKey (org.aion.crypto.ECKey)11 BlockContext (org.aion.zero.impl.types.BlockContext)8 ArrayList (java.util.ArrayList)5 MiningBlock (org.aion.zero.impl.types.MiningBlock)4 AionTxExecSummary (org.aion.base.AionTxExecSummary)3 InternalTransaction (org.aion.types.InternalTransaction)3 BlockchainTestUtils.generateNewBlock (org.aion.zero.impl.blockchain.BlockchainTestUtils.generateNewBlock)3 BlockchainTestUtils.generateNextBlock (org.aion.zero.impl.blockchain.BlockchainTestUtils.generateNextBlock)3 AionTxInfo (org.aion.zero.impl.types.AionTxInfo)3 HashMap (java.util.HashMap)2