Skip to content

Commit

Permalink
Merge pull request #478 from aionnetwork/db-journal-prune
Browse files Browse the repository at this point in the history
Enabling JournalPruneDataSource
  • Loading branch information
AionJayT authored Jun 1, 2018
2 parents 4b5e4f7 + 46fccd6 commit 8ac445d
Show file tree
Hide file tree
Showing 16 changed files with 983 additions and 202 deletions.
70 changes: 46 additions & 24 deletions modAionImpl/src/org/aion/zero/impl/AionHub.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@
*
* This file is part of the aion network project.
*
* The aion network project is free software: you can redistribute it
* and/or modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
* The aion network project is free software: you can redistribute it
* and/or modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or any later version.
*
* The aion network project is distributed in the hope that it will
* be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* The aion network project is distributed in the hope that it will
* be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with the aion network project source files.
* along with the aion network project source files.
* If not, see <https://www.gnu.org/licenses/>.
*
* Contributors:
Expand Down Expand Up @@ -271,9 +271,23 @@ private void loadBlockchain() {
bestBlock != null && // recover only for non-null blocks
!this.repository.isValidRoot(bestBlock.getStateRoot())) {

LOG.info("Recovery initiated due to corrupt world state at block " + bestBlock.getNumber() + ".");

long bestBlockNumber = bestBlock.getNumber();
byte[] bestBlockRoot = bestBlock.getStateRoot();

// ensure that the genesis state exists before attempting recovery
AionGenesis genesis = cfg.getGenesis();
if (!this.repository.isValidRoot(genesis.getStateRoot())) {
LOG.info(
"Corrupt world state for genesis block hash: " + genesis.getShortHash() + ", number: " + genesis
.getNumber() + ".");

buildGenesis(genesis);

LOG.info("Rebuilding genesis block SUCCEEDED.");
}

recovered = this.blockchain.recoverWorldState(this.repository, bestBlock);

if (!this.repository.isValidRoot(bestBlock.getStateRoot())) {
Expand Down Expand Up @@ -324,24 +338,8 @@ private void loadBlockchain() {

AionGenesis genesis = cfg.getGenesis();

// initialization section for network balance contract
IRepositoryCache track = repository.startTracking();

Address networkBalanceAddress = PrecompiledContracts.totalCurrencyAddress;
track.createAccount(networkBalanceAddress);
buildGenesis(genesis);

for (Map.Entry<Integer, BigInteger> addr : genesis.getNetworkBalances().entrySet()) {
track.addStorageRow(networkBalanceAddress, new DataWord(addr.getKey()), new DataWord(addr.getValue()));
}

for (Address addr : genesis.getPremine().keySet()) {
track.createAccount(addr);
track.addBalance(addr, genesis.getPremine().get(addr).getBalance());
}
track.flush();

repository.commitBlock(genesis.getHeader());
this.repository.getBlockStore().saveBlock(genesis, genesis.getDifficultyBI(), true);
blockchain.setBestBlock(genesis);
blockchain.setTotalDifficulty(genesis.getDifficultyBI());

Expand Down Expand Up @@ -396,6 +394,30 @@ private void loadBlockchain() {
// this.repository.getBlockStore().load();
}

private void buildGenesis(AionGenesis genesis) {
// initialization section for network balance contract
IRepositoryCache track = repository.startTracking();

Address networkBalanceAddress = PrecompiledContracts.totalCurrencyAddress;
track.createAccount(networkBalanceAddress);

for (Map.Entry<Integer, BigInteger> addr : genesis.getNetworkBalances().entrySet()) {
track.addStorageRow(
networkBalanceAddress,
new DataWord(addr.getKey()),
new DataWord(addr.getValue()));
}

for (Address addr : genesis.getPremine().keySet()) {
track.createAccount(addr);
track.addBalance(addr, genesis.getPremine().get(addr).getBalance());
}
track.flush();

this.repository.commitBlock(genesis.getHeader());
this.repository.getBlockStore().saveBlock(genesis, genesis.getCumulativeDifficulty(), true);
}

public void close() {
LOG.info("<KERNEL SHUTDOWN SEQUENCE>");

Expand Down
49 changes: 47 additions & 2 deletions modAionImpl/src/org/aion/zero/impl/cli/Cli.java
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,52 @@ public int call(final String[] args, final Cfg cfg) {
}
}
break;
case "--dump-state-size":
long block_count = 2L;

if (args.length < 2) {
System.out.println("Retrieving state size for top " + block_count + " blocks.");
RecoveryUtils.printStateTrieSize(block_count);
} else {
try {
block_count = Long.parseLong(args[1]);
} catch (NumberFormatException e) {
System.out.println("The given argument <" + args[1] + "> cannot be converted to a number.");
}
if (block_count < 1) {
System.out.println("The given argument <" + args[1] + "> is not valid.");
block_count = 2L;
}

System.out.println("Retrieving state size for top " + block_count + " blocks.");
RecoveryUtils.printStateTrieSize(block_count);
}
break;
case "--dump-state":
long level = -1L;

if (args.length < 2) {
System.out.println("Retrieving state for top main chain block...");
RecoveryUtils.printStateTrieDump(level);
} else {
try {
level = Long.parseLong(args[1]);
} catch (NumberFormatException e) {
System.out.println("The given argument <" + args[1] + "> cannot be converted to a number.");
}
if (level == -1L) {
System.out.println("Retrieving state for top main chain block...");
} else {
System.out.println("Retrieving state for main chain block at level " + level + "...");
}
RecoveryUtils.printStateTrieDump(level);
}
break;
case "--db-compact":
RecoveryUtils.dbCompact();
break;
case "--dump-blocks":
long count = 100L;
long count = 10L;

if (args.length < 2) {
System.out.println("Printing top " + count + " blocks from database.");
Expand All @@ -147,10 +188,14 @@ public int call(final String[] args, final Cfg cfg) {
} catch (NumberFormatException e) {
System.out.println("The given argument <" + args[1] + "> cannot be converted to a number.");
}
if (count < 1) {
System.out.println("The given argument <" + args[1] + "> is not valid.");
count = 10L;
}

System.out.println("Printing top " + count + " blocks from database.");
RecoveryUtils.dumpBlocks(count);
}
System.out.println("Finished printing blocks.");
break;
case "-v":
System.out.println("\nVersion");
Expand Down
6 changes: 5 additions & 1 deletion modAionImpl/src/org/aion/zero/impl/db/AionBlockStore.java
Original file line number Diff line number Diff line change
Expand Up @@ -750,11 +750,14 @@ public BigInteger correctIndexEntry(AionBlock block, BigInteger parentTotalDiffi
}
}

public void dumpPastBlocks(long numberOfBlocks, String reportsFolder) throws IOException {
public String dumpPastBlocks(long numberOfBlocks, String reportsFolder) throws IOException {
lock.readLock().lock();

try {
long firstBlock = getMaxNumber();
if (firstBlock < 0) {
return null;
}
long lastBlock = firstBlock - numberOfBlocks;

File file = new File(reportsFolder, System.currentTimeMillis() + "-blocks-report.out");
Expand Down Expand Up @@ -787,6 +790,7 @@ public void dumpPastBlocks(long numberOfBlocks, String reportsFolder) throws IOE
}

writer.close();
return file.getName();
} finally {
lock.readLock().unlock();
}
Expand Down
36 changes: 19 additions & 17 deletions modAionImpl/src/org/aion/zero/impl/db/AionRepositoryImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,12 @@ private static class AionRepositoryImplHolder {
// repository singleton instance
private final static AionRepositoryImpl inst = new AionRepositoryImpl(
new RepositoryConfig(new File(config.getBasePath(), config.getDb().getPath()).getAbsolutePath(),
-1,
config.getDb().getPrune() > 0 ?
// if the value is smaller than backward step
// there is the risk of importing state-less blocks after reboot
(128 > config.getDb().getPrune() ? 128 : config.getDb().getPrune()) :
// negative value => pruning disabled
config.getDb().getPrune(),
ContractDetailsAion.getInstance(),
config.getDb()));
}
Expand Down Expand Up @@ -115,7 +120,7 @@ public TransactionStore<AionTransaction, AionTxReceipt, AionTxInfo> getTransacti
}

private Trie createStateTrie() {
return new SecureTrie(stateDatabase).withPruningEnabled(pruneBlockCount >= 0);
return new SecureTrie(stateDSPrune).withPruningEnabled(pruneBlockCount > 0);
}

@Override
Expand Down Expand Up @@ -501,34 +506,31 @@ public void commitBlock(A0BlockHeader blockHeader) {
worldState.sync();
detailsDS.syncLargeStorage();

// temporarily removed since never used
/* if (pruneBlockCount >= 0) {
stateDSPrune.storeBlockChanges(blockHeader);
detailsDS.getStorageDSPrune().storeBlockChanges(blockHeader);
pruneBlocks(blockHeader);
} */
if (pruneBlockCount > 0) {
stateDSPrune.storeBlockChanges(blockHeader);
detailsDS.getStorageDSPrune().storeBlockChanges(blockHeader);
pruneBlocks(blockHeader);
}
} finally {
rwLock.writeLock().unlock();
}
}

// TODO-AR: reenable state pruning
// temporarily removed since never used
/* private void pruneBlocks(A0BlockHeader curBlock) {
if (curBlock.getNumber() > bestBlockNumber) { // pruning only on
// increasing blocks
private void pruneBlocks(A0BlockHeader curBlock) {
if (curBlock.getNumber() > bestBlockNumber) {
// pruning only on increasing blocks
long pruneBlockNumber = curBlock.getNumber() - pruneBlockCount;
if (pruneBlockNumber >= 0) {
byte[] pruneBlockHash = blockStore.getBlockHashByNumber(pruneBlockNumber);
if (pruneBlockHash != null) {
A0BlockHeader header = blockStore.getBlockByHash(pruneBlockHash).getHeader();
// stateDSPrune.prune(header);
// detailsDS.getStorageDSPrune().prune(header);
stateDSPrune.prune(header);
detailsDS.getStorageDSPrune().prune(header);
}
}
}
bestBlockNumber = curBlock.getNumber();
} */
}

public Trie getWorldState() {
return worldState;
Expand All @@ -543,7 +545,7 @@ public IRepository getSnapshotTo(byte[] root) {
repo.blockStore = blockStore;
repo.cfg = cfg;
repo.stateDatabase = this.stateDatabase;
// repo.stateDSPrune = this.stateDSPrune;
repo.stateDSPrune = this.stateDSPrune;
repo.pruneBlockCount = this.pruneBlockCount;
repo.detailsDS = this.detailsDS;
repo.isSnapshot = true;
Expand Down
Loading

0 comments on commit 8ac445d

Please sign in to comment.