Added missing merge files.
This commit is contained in:
parent
74eca228dc
commit
e376bfc922
|
@ -0,0 +1,16 @@
|
|||
package org.ethereum.datasource;
|
||||
|
||||
/**
|
||||
* @author Mikhail Kalinin
|
||||
* @since 07.07.2015
|
||||
*/
|
||||
public interface DataSource {
|
||||
|
||||
void init();
|
||||
|
||||
void setName(String name);
|
||||
|
||||
String getName();
|
||||
|
||||
void close();
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package org.ethereum.datasource;
|
||||
|
||||
/**
|
||||
* @author Mikhail Kalinin
|
||||
* @since 07.07.2015
|
||||
*/
|
||||
public interface QueueDataSource extends DataSource {
|
||||
|
||||
void offerFirst(byte[] e);
|
||||
|
||||
byte[] peekFirst();
|
||||
|
||||
byte[] pollFirst();
|
||||
|
||||
void offerLast(byte[] e);
|
||||
|
||||
byte[] peekLast();
|
||||
|
||||
byte[] pollLast();
|
||||
|
||||
boolean isEmpty();
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
package org.ethereum.datasource.mapdb;
|
||||
|
||||
import org.ethereum.config.SystemProperties;
|
||||
import org.ethereum.datasource.QueueDataSource;
|
||||
import org.mapdb.BTreeMap;
|
||||
import org.mapdb.DB;
|
||||
import org.mapdb.DBMaker;
|
||||
import org.mapdb.Serializer;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import static java.lang.System.getProperty;
|
||||
|
||||
/**
|
||||
* @author Mikhail Kalinin
|
||||
* @since 07.07.2015
|
||||
*/
|
||||
public class MapDBQueueDataSource implements QueueDataSource {
|
||||
|
||||
private DB db;
|
||||
private BTreeMap<Long, byte[]> map;
|
||||
private String name;
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
File dbFile = new File(getProperty("user.dir") + "/" + SystemProperties.CONFIG.databaseDir() + "/" + name);
|
||||
if (!dbFile.getParentFile().exists()) dbFile.getParentFile().mkdirs();
|
||||
|
||||
db = DBMaker.fileDB(dbFile)
|
||||
.transactionDisable()
|
||||
.closeOnJvmShutdown()
|
||||
.make();
|
||||
|
||||
map = db.treeMapCreate(name)
|
||||
.keySerializer(Serializer.LONG)
|
||||
.valueSerializer(Serializer.BYTE_ARRAY)
|
||||
.makeOrGet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
db.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void offerFirst(byte[] e) {
|
||||
if(map.isEmpty()) {
|
||||
offerEmpty(e);
|
||||
} else {
|
||||
map.put(map.firstKey() - 1, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized byte[] peekFirst() {
|
||||
if(map.isEmpty()) {
|
||||
return null;
|
||||
} else {
|
||||
return map.firstEntry().getValue();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized byte[] pollFirst() {
|
||||
if(map.isEmpty()) {
|
||||
return null;
|
||||
} else {
|
||||
return map.pollFirstEntry().getValue();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void offerLast(byte[] e) {
|
||||
if(map.isEmpty()) {
|
||||
offerEmpty(e);
|
||||
} else {
|
||||
map.put(map.lastKey() + 1, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized byte[] peekLast() {
|
||||
if(map.isEmpty()) {
|
||||
return null;
|
||||
} else {
|
||||
return map.lastEntry().getValue();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized byte[] pollLast() {
|
||||
if(map.isEmpty()) {
|
||||
return null;
|
||||
} else {
|
||||
return map.pollLastEntry().getValue();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return map.isEmpty();
|
||||
}
|
||||
|
||||
private void offerEmpty(byte[] e) {
|
||||
map.put(0L, e);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
package org.ethereum.db;
|
||||
|
||||
import org.ethereum.datasource.QueueDataSource;
|
||||
import org.ethereum.datasource.mapdb.MapDBQueueDataSource;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author Mikhail Kalinin
|
||||
* @since 07.07.2015
|
||||
*/
|
||||
public class HashStore {
|
||||
|
||||
private static final String DEFAULT_NAME = "hashstore";
|
||||
|
||||
private QueueDataSource hashes;
|
||||
|
||||
private HashStore() {
|
||||
}
|
||||
|
||||
public void add(byte[] hash) {
|
||||
hashes.offerLast(hash);
|
||||
}
|
||||
|
||||
public byte[] peek() {
|
||||
return hashes.peekFirst();
|
||||
}
|
||||
|
||||
public byte[] poll() {
|
||||
return hashes.pollFirst();
|
||||
}
|
||||
|
||||
public void addFirst(byte[] hash) {
|
||||
hashes.offerFirst(hash);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return hashes.isEmpty();
|
||||
}
|
||||
|
||||
public void close() {
|
||||
hashes.close();
|
||||
}
|
||||
|
||||
static class Builder {
|
||||
private String name = DEFAULT_NAME;
|
||||
private Class<? extends QueueDataSource> dataSourceClass = MapDBQueueDataSource.class;
|
||||
|
||||
public Builder withDataSource(Class<? extends QueueDataSource> dataSourceClass) {
|
||||
this.dataSourceClass = dataSourceClass;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withName(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public HashStore build() throws IllegalAccessException, InstantiationException {
|
||||
HashStore store = new HashStore();
|
||||
store.hashes = dataSourceClass.newInstance();
|
||||
store.hashes.setName(name);
|
||||
store.hashes.init();
|
||||
return store;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,275 @@
|
|||
package org.ethereum.db;
|
||||
|
||||
import org.ethereum.core.Block;
|
||||
import org.ethereum.datasource.KeyValueDataSource;
|
||||
import org.mapdb.DataIO;
|
||||
import org.mapdb.Serializer;
|
||||
|
||||
import java.io.*;
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class IndexedBlockStore {
|
||||
|
||||
IndexedBlockStore cache;
|
||||
Map<Long, List<BlockInfo>> index;
|
||||
KeyValueDataSource blocks;
|
||||
|
||||
public IndexedBlockStore(){
|
||||
}
|
||||
|
||||
public void init(Map<Long, List<BlockInfo>> index, KeyValueDataSource blocks, IndexedBlockStore cache) {
|
||||
this.cache = cache;
|
||||
this.index = index;
|
||||
this.blocks = blocks;
|
||||
}
|
||||
|
||||
public void flush(){
|
||||
|
||||
for (byte[] hash : cache.blocks.keys()){
|
||||
blocks.put(hash, cache.blocks.get(hash));
|
||||
}
|
||||
|
||||
index.putAll( cache.index );
|
||||
|
||||
cache.blocks.close();
|
||||
cache.index.clear();
|
||||
}
|
||||
|
||||
|
||||
public void addBlock(Block block, BigInteger cummDifficulty, boolean mainChain){
|
||||
if (cache == null)
|
||||
addInternalBlock(block, cummDifficulty, mainChain);
|
||||
else
|
||||
cache.addBlock(block, cummDifficulty, mainChain);
|
||||
}
|
||||
|
||||
private void addInternalBlock(Block block, BigInteger cummDifficulty, boolean mainChain){
|
||||
|
||||
List<BlockInfo> blockInfos = index.get(block.getNumber());
|
||||
if (blockInfos == null){
|
||||
blockInfos = new ArrayList<>();
|
||||
}
|
||||
|
||||
BlockInfo blockInfo = new BlockInfo();
|
||||
blockInfo.setCummDifficulty(cummDifficulty);
|
||||
blockInfo.setHash(block.getHash());
|
||||
blockInfo.setMainChain(mainChain); // FIXME:maybe here I should force reset main chain for all uncles on that level
|
||||
|
||||
blockInfos.add(blockInfo);
|
||||
index.put(block.getNumber(), blockInfos);
|
||||
|
||||
blocks.put(block.getHash(), block.getEncoded());
|
||||
}
|
||||
|
||||
public List<Block> getBlocksByNumber(long number){
|
||||
|
||||
List<Block> result = new ArrayList<>();
|
||||
if (cache != null)
|
||||
result = cache.getBlocksByNumber(number);
|
||||
|
||||
List<BlockInfo> blockInfos = index.get(number);
|
||||
if (blockInfos == null){
|
||||
return result;
|
||||
}
|
||||
|
||||
for (BlockInfo blockInfo : blockInfos){
|
||||
|
||||
byte[] hash = blockInfo.getHash();
|
||||
byte[] blockRlp = blocks.get(hash);
|
||||
|
||||
result.add(new Block(blockRlp));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public Block getChainBlockByNumber(long number){
|
||||
|
||||
if (cache != null) {
|
||||
Block block = cache.getChainBlockByNumber(number);
|
||||
if (block != null) return block;
|
||||
}
|
||||
|
||||
List<BlockInfo> blockInfos = index.get(number);
|
||||
if (blockInfos == null){
|
||||
return null;
|
||||
}
|
||||
|
||||
for (BlockInfo blockInfo : blockInfos){
|
||||
|
||||
if (blockInfo.isMainChain()){
|
||||
|
||||
byte[] hash = blockInfo.getHash();
|
||||
byte[] blockRlp = blocks.get(hash);
|
||||
return new Block(blockRlp);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Block getBlockByHash(byte[] hash) {
|
||||
|
||||
if (cache != null) {
|
||||
Block cachedBlock = cache.getBlockByHash(hash);
|
||||
if (cachedBlock != null) return cachedBlock;
|
||||
}
|
||||
|
||||
byte[] blockRlp = blocks.get(hash);
|
||||
if (blockRlp == null)
|
||||
return null;
|
||||
|
||||
return new Block(blockRlp);
|
||||
}
|
||||
|
||||
public BigInteger getTotalDifficulty(){
|
||||
|
||||
BigInteger cacheTotalDifficulty = BigInteger.ZERO;
|
||||
|
||||
long maxNumber = getMaxNumber();
|
||||
if (cache != null) {
|
||||
List<BlockInfo> infos = cache.index.get(maxNumber);
|
||||
if (infos != null){
|
||||
for (BlockInfo blockInfo : infos){
|
||||
if (blockInfo.isMainChain()){
|
||||
return blockInfo.getCummDifficulty();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<BlockInfo> blockInfos = index.get(maxNumber);
|
||||
for (BlockInfo blockInfo : blockInfos){
|
||||
if (blockInfo.isMainChain()){
|
||||
return blockInfo.getCummDifficulty();
|
||||
}
|
||||
}
|
||||
|
||||
return cacheTotalDifficulty;
|
||||
}
|
||||
|
||||
public long getMaxNumber(){
|
||||
|
||||
Long bestIndex = 0L;
|
||||
|
||||
if (index.size() > 0){
|
||||
bestIndex = (long) index.size();
|
||||
}
|
||||
|
||||
if (cache != null){
|
||||
return bestIndex + cache.index.size() - 1L;
|
||||
} else
|
||||
return bestIndex - 1L;
|
||||
}
|
||||
|
||||
public List<byte[]> getNHashesEndWith(byte[] hash, long number){
|
||||
|
||||
List<byte[]> cachedHashes = new ArrayList<>();
|
||||
if (cache != null)
|
||||
cachedHashes = cache.getNHashesEndWith(hash, number);
|
||||
|
||||
byte[] rlp = blocks.get(hash);
|
||||
if (rlp == null) return cachedHashes;
|
||||
|
||||
for (int i = 0; i < number; ++i){
|
||||
|
||||
Block block = new Block(rlp);
|
||||
cachedHashes.add(block.getHash());
|
||||
rlp = blocks.get(block.getParentHash());
|
||||
if (rlp == null) break;
|
||||
}
|
||||
|
||||
return cachedHashes;
|
||||
}
|
||||
|
||||
public List<byte[]> getNHashesStartWith(long number, long maxBlocks){
|
||||
|
||||
|
||||
List<byte[]> result = new ArrayList<>();
|
||||
|
||||
int i;
|
||||
for ( i = 0; i < maxBlocks; ++i){
|
||||
List<BlockInfo> blockInfos = index.get(number);
|
||||
if (blockInfos == null) break;
|
||||
|
||||
for (BlockInfo blockInfo : blockInfos)
|
||||
if (blockInfo.isMainChain()){
|
||||
result.add(blockInfo.getHash());
|
||||
break;
|
||||
}
|
||||
|
||||
++number;
|
||||
}
|
||||
maxBlocks -= i;
|
||||
|
||||
if (cache != null)
|
||||
result.addAll( cache.getNHashesStartWith(number, maxBlocks) );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static class BlockInfo implements Serializable {
|
||||
byte[] hash;
|
||||
BigInteger cummDifficulty;
|
||||
boolean mainChain;
|
||||
|
||||
public byte[] getHash() {
|
||||
return hash;
|
||||
}
|
||||
|
||||
public void setHash(byte[] hash) {
|
||||
this.hash = hash;
|
||||
}
|
||||
|
||||
public BigInteger getCummDifficulty() {
|
||||
return cummDifficulty;
|
||||
}
|
||||
|
||||
public void setCummDifficulty(BigInteger cummDifficulty) {
|
||||
this.cummDifficulty = cummDifficulty;
|
||||
}
|
||||
|
||||
public boolean isMainChain() {
|
||||
return mainChain;
|
||||
}
|
||||
|
||||
public void setMainChain(boolean mainChain) {
|
||||
this.mainChain = mainChain;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static final Serializer<List<BlockInfo>> BLOCK_INFO_SERIALIZER = new Serializer<List<BlockInfo>>(){
|
||||
|
||||
@Override
|
||||
public void serialize(DataOutput out, List<BlockInfo> value) throws IOException {
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos = new ObjectOutputStream(bos);
|
||||
oos.writeObject(value);
|
||||
|
||||
byte[] data = bos.toByteArray();
|
||||
DataIO.packInt(out, data.length);
|
||||
out.write(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BlockInfo> deserialize(DataInput in, int available) throws IOException {
|
||||
|
||||
List<BlockInfo> value = null;
|
||||
try {
|
||||
int size = DataIO.unpackInt(in);
|
||||
byte[] data = new byte[size];
|
||||
in.readFully(data);
|
||||
|
||||
ByteArrayInputStream bis = new ByteArrayInputStream(data, 0, data.length);
|
||||
ObjectInputStream ois = new ObjectInputStream(bis);
|
||||
value = (List<BlockInfo>)ois.readObject();
|
||||
|
||||
} catch (ClassNotFoundException e) {e.printStackTrace();}
|
||||
|
||||
return value;
|
||||
}
|
||||
};
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package org.ethereum.util;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class FileUtil {
|
||||
|
||||
public static boolean recursiveDelete(String fileName) {
|
||||
File file = new File(fileName);
|
||||
if (file.exists()) {
|
||||
//check if the file is a directory
|
||||
if (file.isDirectory()) {
|
||||
if ((file.list()).length > 0) {
|
||||
for(String s:file.list()){
|
||||
//call deletion of file individually
|
||||
recursiveDelete(fileName + System.getProperty("file.separator") + s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
file.setWritable(true);
|
||||
boolean result = file.delete();
|
||||
return result;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,141 @@
|
|||
package org.ethereum.db;
|
||||
|
||||
import org.ethereum.config.SystemProperties;
|
||||
import org.ethereum.util.FileUtil;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
/**
|
||||
* @author Mikhail Kalinin
|
||||
* @since 07.07.2015
|
||||
*/
|
||||
public class HashStoreTest {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger("test");
|
||||
|
||||
private List<byte[]> hashes = new ArrayList<>();
|
||||
private HashStore hashStore;
|
||||
private String testDb;
|
||||
|
||||
@Before
|
||||
public void setup() throws InstantiationException, IllegalAccessException {
|
||||
Random rnd = new Random(System.currentTimeMillis());
|
||||
for(int i = 0; i < 50; i++) {
|
||||
byte[] hash = new byte[32];
|
||||
rnd.nextBytes(hash);
|
||||
hashes.add(hash);
|
||||
}
|
||||
|
||||
BigInteger bi = new BigInteger(32, new Random());
|
||||
testDb = "test_db_" + bi;
|
||||
SystemProperties.CONFIG.setDataBaseDir(testDb);
|
||||
hashStore = new HashStore.Builder().build();
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanup() {
|
||||
hashStore.close();
|
||||
FileUtil.recursiveDelete(testDb);
|
||||
}
|
||||
|
||||
@Test // FIFO, add first
|
||||
public void test1() throws InstantiationException, IllegalAccessException {
|
||||
for(byte[] hash : hashes) {
|
||||
hashStore.add(hash);
|
||||
}
|
||||
|
||||
// testing peek and poll
|
||||
assertArrayEquals(hashes.get(0), hashStore.peek());
|
||||
for(byte[] hash : hashes) {
|
||||
assertArrayEquals(hash, hashStore.poll());
|
||||
}
|
||||
assertEquals(true, hashStore.isEmpty());
|
||||
assertNull(hashStore.peek());
|
||||
assertNull(hashStore.poll());
|
||||
|
||||
// testing addFirst
|
||||
for(int i = 0; i < 10; i++) {
|
||||
hashStore.add(hashes.get(i));
|
||||
}
|
||||
for(int i = 10; i < 20; i++) {
|
||||
hashStore.addFirst(hashes.get(i));
|
||||
}
|
||||
for(int i = 19; i >= 10; i--) {
|
||||
assertArrayEquals(hashes.get(i), hashStore.poll());
|
||||
}
|
||||
}
|
||||
|
||||
@Test // concurrency
|
||||
public void test2() throws InstantiationException, IllegalAccessException, InterruptedException {
|
||||
new Thread(new Writer(1)).start();
|
||||
new Thread(new Writer(2)).start();
|
||||
new Thread(new Writer(3)).start();
|
||||
new Thread(new Reader(1)).start();
|
||||
Thread r2 = new Thread(new Reader(2));
|
||||
r2.start();
|
||||
r2.join();
|
||||
}
|
||||
|
||||
private class Reader implements Runnable {
|
||||
|
||||
private int index;
|
||||
|
||||
public Reader(int index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
int nullsCount = 0;
|
||||
while (nullsCount < 5) {
|
||||
byte[] hash = hashStore.poll();
|
||||
logger.info("reader {}: {}", index, hash == null ? null : Hex.toHexString(hash));
|
||||
if(hash == null) {
|
||||
nullsCount++;
|
||||
} else {
|
||||
nullsCount = 0;
|
||||
}
|
||||
Thread.sleep(50);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
logger.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class Writer implements Runnable {
|
||||
|
||||
private int index;
|
||||
|
||||
public Writer(int index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
for(byte[] hash : hashes) {
|
||||
hashStore.add(hash);
|
||||
logger.info("writer {}: {}", index, Hex.toHexString(hash));
|
||||
Thread.sleep(50);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
logger.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,709 @@
|
|||
package org.ethereum.db;
|
||||
|
||||
import org.ethereum.config.SystemProperties;
|
||||
import org.ethereum.core.Block;
|
||||
import org.ethereum.core.Genesis;
|
||||
import org.ethereum.datasource.HashMapDB;
|
||||
import org.ethereum.datasource.KeyValueDataSource;
|
||||
import org.ethereum.datasource.LevelDbDataSource;
|
||||
import org.ethereum.util.FileUtil;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mapdb.DB;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.util.*;
|
||||
|
||||
import static java.math.BigInteger.ZERO;
|
||||
import static org.ethereum.TestUtils.createIndexMap;
|
||||
import static org.ethereum.TestUtils.createMapDB;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
|
||||
public class IndexedBlockStoreTest {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger("test");
|
||||
private List<Block> blocks = new ArrayList<>();
|
||||
private BigInteger cumDifficulty = ZERO;
|
||||
|
||||
@Before
|
||||
public void setup() throws URISyntaxException, IOException {
|
||||
|
||||
URL scenario1 = ClassLoader
|
||||
.getSystemResource("blockstore/load.dmp");
|
||||
|
||||
File file = new File(scenario1.toURI());
|
||||
List<String> strData = Files.readAllLines(file.toPath(), StandardCharsets.UTF_8);
|
||||
|
||||
Block genesis = Genesis.getInstance();
|
||||
blocks.add(genesis);
|
||||
cumDifficulty = cumDifficulty.add(genesis.getCumulativeDifficulty());
|
||||
|
||||
for (String blockRLP : strData) {
|
||||
|
||||
Block block = new Block(
|
||||
Hex.decode(blockRLP));
|
||||
|
||||
if (block.getNumber() % 1000 == 0)
|
||||
logger.info("adding block.hash: [{}] block.number: [{}]",
|
||||
block.getShortHash(),
|
||||
block.getNumber());
|
||||
|
||||
blocks.add(block);
|
||||
cumDifficulty = cumDifficulty.add(block.getCumulativeDifficulty());
|
||||
}
|
||||
|
||||
logger.info("total difficulty: {}", cumDifficulty);
|
||||
logger.info("total blocks loaded: {}", blocks.size());
|
||||
}
|
||||
|
||||
|
||||
@Test // no cache, save some load, and check it exist
|
||||
public void test1(){
|
||||
|
||||
IndexedBlockStore indexedBlockStore = new IndexedBlockStore();
|
||||
indexedBlockStore.init(new HashMap<Long, List<IndexedBlockStore.BlockInfo>>(), new HashMapDB(), null);
|
||||
|
||||
BigInteger cummDiff = BigInteger.ZERO;
|
||||
for (Block block : blocks){
|
||||
cummDiff = cummDiff.add( block.getCumulativeDifficulty() );
|
||||
indexedBlockStore.addBlock(block, cummDiff, true);
|
||||
}
|
||||
|
||||
// testing: getTotalDifficulty()
|
||||
// testing: getMaxNumber()
|
||||
|
||||
long bestIndex = blocks.get(blocks.size() - 1).getNumber();
|
||||
assertEquals(bestIndex, indexedBlockStore.getMaxNumber());
|
||||
assertEquals(cumDifficulty, indexedBlockStore.getTotalDifficulty());
|
||||
|
||||
// testing: getBlockByHash(byte[])
|
||||
|
||||
Block block = blocks.get(50);
|
||||
Block block_ = indexedBlockStore.getBlockByHash(block.getHash());
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(150);
|
||||
block_ = indexedBlockStore.getBlockByHash(block.getHash());
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(0);
|
||||
block_ = indexedBlockStore.getBlockByHash(block.getHash());
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(8003);
|
||||
block_ = indexedBlockStore.getBlockByHash(block.getHash());
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block_ = indexedBlockStore.getBlockByHash(Hex.decode("00112233"));
|
||||
assertEquals(null, block_);
|
||||
|
||||
// testing: getChainBlockByNumber(long)
|
||||
|
||||
block = blocks.get(50);
|
||||
block_ = indexedBlockStore.getChainBlockByNumber(block.getNumber());
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(150);
|
||||
block_ = indexedBlockStore.getChainBlockByNumber(block.getNumber());
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(0);
|
||||
block_ = indexedBlockStore.getChainBlockByNumber(block.getNumber());
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(8003);
|
||||
block_ = indexedBlockStore.getChainBlockByNumber(block.getNumber());
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block_ = indexedBlockStore.getChainBlockByNumber(10000);
|
||||
assertEquals(null, block_);
|
||||
|
||||
// testing: getBlocksByNumber(long)
|
||||
|
||||
block = blocks.get(50);
|
||||
block_ = indexedBlockStore.getBlocksByNumber(block.getNumber()).get(0);
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(150);
|
||||
block_ = indexedBlockStore.getBlocksByNumber(block.getNumber()).get(0);
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(0);
|
||||
block_ = indexedBlockStore.getBlocksByNumber(block.getNumber()).get(0);
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(8003);
|
||||
block_ = indexedBlockStore.getBlocksByNumber(block.getNumber()).get(0);
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
int blocksNum = indexedBlockStore.getBlocksByNumber(10000).size();
|
||||
assertEquals(0, blocksNum);
|
||||
|
||||
// testing: getNHashesEndWith(byte[], long)
|
||||
|
||||
block = blocks.get(8003);
|
||||
List<byte[]> hashList = indexedBlockStore.getNHashesEndWith(block.getHash(), 100);
|
||||
for (int i = 0; i < 100; ++i){
|
||||
block = blocks.get(8003 - i);
|
||||
String hash = Hex.toHexString(hashList.get(i));
|
||||
String hash_ = Hex.toHexString( block.getHash() );
|
||||
assertEquals(hash_, hash);
|
||||
}
|
||||
|
||||
// testing: getNHashesStartWith(long, long)
|
||||
|
||||
block = blocks.get(7003);
|
||||
hashList = indexedBlockStore.getNHashesStartWith(block.getNumber(), 100);
|
||||
for (int i = 0; i < 100; ++i){
|
||||
block = blocks.get(7003 + i);
|
||||
String hash = Hex.toHexString(hashList.get(i));
|
||||
String hash_ = Hex.toHexString( block.getHash() );
|
||||
assertEquals(hash_, hash);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test // predefined cache, save some load, and check it exist
|
||||
public void test2(){
|
||||
|
||||
IndexedBlockStore cache = new IndexedBlockStore();
|
||||
cache.init(new HashMap<Long, List<IndexedBlockStore.BlockInfo>>(), new HashMapDB(), null);
|
||||
|
||||
IndexedBlockStore indexedBlockStore = new IndexedBlockStore();
|
||||
indexedBlockStore.init(new HashMap<Long, List<IndexedBlockStore.BlockInfo>>(), new HashMapDB(), cache);
|
||||
|
||||
BigInteger cummDiff = BigInteger.ZERO;
|
||||
for (Block block : blocks){
|
||||
cummDiff = cummDiff.add( block.getCumulativeDifficulty() );
|
||||
indexedBlockStore.addBlock(block, cummDiff, true);
|
||||
}
|
||||
|
||||
// testing: getTotalDifficulty()
|
||||
// testing: getMaxNumber()
|
||||
|
||||
long bestIndex = blocks.get(blocks.size() - 1).getNumber();
|
||||
assertEquals(bestIndex, indexedBlockStore.getMaxNumber());
|
||||
assertEquals(cumDifficulty, indexedBlockStore.getTotalDifficulty());
|
||||
|
||||
// testing: getBlockByHash(byte[])
|
||||
|
||||
Block block = blocks.get(50);
|
||||
Block block_ = indexedBlockStore.getBlockByHash(block.getHash());
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(150);
|
||||
block_ = indexedBlockStore.getBlockByHash(block.getHash());
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(0);
|
||||
block_ = indexedBlockStore.getBlockByHash(block.getHash());
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(8003);
|
||||
block_ = indexedBlockStore.getBlockByHash(block.getHash());
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block_ = indexedBlockStore.getBlockByHash(Hex.decode("00112233"));
|
||||
assertEquals(null, block_);
|
||||
|
||||
// testing: getChainBlockByNumber(long)
|
||||
|
||||
block = blocks.get(50);
|
||||
block_ = indexedBlockStore.getChainBlockByNumber(block.getNumber());
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(150);
|
||||
block_ = indexedBlockStore.getChainBlockByNumber(block.getNumber());
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(0);
|
||||
block_ = indexedBlockStore.getChainBlockByNumber(block.getNumber());
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(8003);
|
||||
block_ = indexedBlockStore.getChainBlockByNumber(block.getNumber());
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block_ = indexedBlockStore.getChainBlockByNumber(10000);
|
||||
assertEquals(null, block_);
|
||||
|
||||
// testing: getBlocksByNumber(long)
|
||||
|
||||
block = blocks.get(50);
|
||||
block_ = indexedBlockStore.getBlocksByNumber(block.getNumber()).get(0);
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(150);
|
||||
block_ = indexedBlockStore.getBlocksByNumber(block.getNumber()).get(0);
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(0);
|
||||
block_ = indexedBlockStore.getBlocksByNumber(block.getNumber()).get(0);
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(8003);
|
||||
block_ = indexedBlockStore.getBlocksByNumber(block.getNumber()).get(0);
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
int blocksNum = indexedBlockStore.getBlocksByNumber(10000).size();
|
||||
assertEquals(0, blocksNum);
|
||||
|
||||
// testing: getNHashesEndWith(byte[], long)
|
||||
|
||||
block = blocks.get(8003);
|
||||
List<byte[]> hashList = indexedBlockStore.getNHashesEndWith(block.getHash(), 100);
|
||||
for (int i = 0; i < 100; ++i){
|
||||
block = blocks.get(8003 - i);
|
||||
String hash = Hex.toHexString(hashList.get(i));
|
||||
String hash_ = Hex.toHexString( block.getHash() );
|
||||
assertEquals(hash_, hash);
|
||||
}
|
||||
|
||||
// testing: getNHashesStartWith(long, long)
|
||||
|
||||
block = blocks.get(7003);
|
||||
hashList = indexedBlockStore.getNHashesStartWith(block.getNumber(), 100);
|
||||
for (int i = 0; i < 100; ++i){
|
||||
block = blocks.get(7003 + i);
|
||||
String hash = Hex.toHexString(hashList.get(i));
|
||||
String hash_ = Hex.toHexString( block.getHash() );
|
||||
assertEquals(hash_, hash);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test // predefined cache loaded and flushed, check it exist
|
||||
public void test3(){
|
||||
|
||||
IndexedBlockStore cache = new IndexedBlockStore();
|
||||
cache.init(new HashMap<Long, List<IndexedBlockStore.BlockInfo>>(), new HashMapDB(), null);
|
||||
|
||||
IndexedBlockStore indexedBlockStore = new IndexedBlockStore();
|
||||
indexedBlockStore.init(new HashMap<Long, List<IndexedBlockStore.BlockInfo>>(), new HashMapDB(), cache);
|
||||
|
||||
BigInteger cummDiff = BigInteger.ZERO;
|
||||
for (Block block : blocks){
|
||||
cummDiff = cummDiff.add( block.getCumulativeDifficulty() );
|
||||
indexedBlockStore.addBlock(block, cummDiff, true);
|
||||
}
|
||||
|
||||
indexedBlockStore.flush();
|
||||
|
||||
// testing: getTotalDifficulty()
|
||||
// testing: getMaxNumber()
|
||||
|
||||
long bestIndex = blocks.get(blocks.size() - 1).getNumber();
|
||||
assertEquals(bestIndex, indexedBlockStore.getMaxNumber());
|
||||
assertEquals(cumDifficulty, indexedBlockStore.getTotalDifficulty());
|
||||
|
||||
// testing: getBlockByHash(byte[])
|
||||
|
||||
Block block = blocks.get(50);
|
||||
Block block_ = indexedBlockStore.getBlockByHash(block.getHash());
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(150);
|
||||
block_ = indexedBlockStore.getBlockByHash(block.getHash());
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(0);
|
||||
block_ = indexedBlockStore.getBlockByHash(block.getHash());
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(8003);
|
||||
block_ = indexedBlockStore.getBlockByHash(block.getHash());
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block_ = indexedBlockStore.getBlockByHash(Hex.decode("00112233"));
|
||||
assertEquals(null, block_);
|
||||
|
||||
// testing: getChainBlockByNumber(long)
|
||||
|
||||
block = blocks.get(50);
|
||||
block_ = indexedBlockStore.getChainBlockByNumber(block.getNumber());
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(150);
|
||||
block_ = indexedBlockStore.getChainBlockByNumber(block.getNumber());
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(0);
|
||||
block_ = indexedBlockStore.getChainBlockByNumber(block.getNumber());
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(8003);
|
||||
block_ = indexedBlockStore.getChainBlockByNumber(block.getNumber());
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block_ = indexedBlockStore.getChainBlockByNumber(10000);
|
||||
assertEquals(null, block_);
|
||||
|
||||
// testing: getBlocksByNumber(long)
|
||||
|
||||
block = blocks.get(50);
|
||||
block_ = indexedBlockStore.getBlocksByNumber(block.getNumber()).get(0);
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(150);
|
||||
block_ = indexedBlockStore.getBlocksByNumber(block.getNumber()).get(0);
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(0);
|
||||
block_ = indexedBlockStore.getBlocksByNumber(block.getNumber()).get(0);
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(8003);
|
||||
block_ = indexedBlockStore.getBlocksByNumber(block.getNumber()).get(0);
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
int blocksNum = indexedBlockStore.getBlocksByNumber(10000).size();
|
||||
assertEquals(0, blocksNum);
|
||||
|
||||
// testing: getNHashesEndWith(byte[], long)
|
||||
|
||||
block = blocks.get(8003);
|
||||
List<byte[]> hashList = indexedBlockStore.getNHashesEndWith(block.getHash(), 100);
|
||||
for (int i = 0; i < 100; ++i){
|
||||
block = blocks.get(8003 - i);
|
||||
String hash = Hex.toHexString(hashList.get(i));
|
||||
String hash_ = Hex.toHexString( block.getHash() );
|
||||
assertEquals(hash_, hash);
|
||||
}
|
||||
|
||||
// testing: getNHashesStartWith(long, long)
|
||||
|
||||
block = blocks.get(7003);
|
||||
hashList = indexedBlockStore.getNHashesStartWith(block.getNumber(), 100);
|
||||
for (int i = 0; i < 100; ++i){
|
||||
block = blocks.get(7003 + i);
|
||||
String hash = Hex.toHexString(hashList.get(i));
|
||||
String hash_ = Hex.toHexString( block.getHash() );
|
||||
assertEquals(hash_, hash);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test // cache + leveldb + mapdb, save some load, flush to disk, and check it exist
|
||||
public void test4() throws IOException {
|
||||
|
||||
BigInteger bi = new BigInteger(32, new Random());
|
||||
String testDir = "test_db_" + bi;
|
||||
SystemProperties.CONFIG.setDataBaseDir(testDir);
|
||||
|
||||
DB db = createMapDB(testDir);
|
||||
Map<Long, List<IndexedBlockStore.BlockInfo>> indexDB = createIndexMap(db);
|
||||
|
||||
KeyValueDataSource blocksDB = new LevelDbDataSource("blocks");
|
||||
blocksDB.init();
|
||||
|
||||
IndexedBlockStore indexedBlockStore = new IndexedBlockStore();
|
||||
indexedBlockStore.init(indexDB, blocksDB, null);
|
||||
|
||||
|
||||
BigInteger cummDiff = BigInteger.ZERO;
|
||||
for (Block block : blocks){
|
||||
cummDiff = cummDiff.add( block.getCumulativeDifficulty() );
|
||||
indexedBlockStore.addBlock(block, cummDiff, true);
|
||||
}
|
||||
|
||||
// testing: getTotalDifficulty()
|
||||
// testing: getMaxNumber()
|
||||
|
||||
long bestIndex = blocks.get(blocks.size() - 1).getNumber();
|
||||
assertEquals(bestIndex, indexedBlockStore.getMaxNumber());
|
||||
assertEquals(cumDifficulty, indexedBlockStore.getTotalDifficulty());
|
||||
|
||||
// testing: getBlockByHash(byte[])
|
||||
|
||||
Block block = blocks.get(50);
|
||||
Block block_ = indexedBlockStore.getBlockByHash(block.getHash());
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(150);
|
||||
block_ = indexedBlockStore.getBlockByHash(block.getHash());
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(0);
|
||||
block_ = indexedBlockStore.getBlockByHash(block.getHash());
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(8003);
|
||||
block_ = indexedBlockStore.getBlockByHash(block.getHash());
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block_ = indexedBlockStore.getBlockByHash(Hex.decode("00112233"));
|
||||
assertEquals(null, block_);
|
||||
|
||||
// testing: getChainBlockByNumber(long)
|
||||
|
||||
block = blocks.get(50);
|
||||
block_ = indexedBlockStore.getChainBlockByNumber(block.getNumber());
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(150);
|
||||
block_ = indexedBlockStore.getChainBlockByNumber(block.getNumber());
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(0);
|
||||
block_ = indexedBlockStore.getChainBlockByNumber(block.getNumber());
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(8003);
|
||||
block_ = indexedBlockStore.getChainBlockByNumber(block.getNumber());
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block_ = indexedBlockStore.getChainBlockByNumber(10000);
|
||||
assertEquals(null, block_);
|
||||
|
||||
// testing: getBlocksByNumber(long)
|
||||
|
||||
block = blocks.get(50);
|
||||
block_ = indexedBlockStore.getBlocksByNumber(block.getNumber()).get(0);
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(150);
|
||||
block_ = indexedBlockStore.getBlocksByNumber(block.getNumber()).get(0);
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(0);
|
||||
block_ = indexedBlockStore.getBlocksByNumber(block.getNumber()).get(0);
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(8003);
|
||||
block_ = indexedBlockStore.getBlocksByNumber(block.getNumber()).get(0);
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
int blocksNum = indexedBlockStore.getBlocksByNumber(10000).size();
|
||||
assertEquals(0, blocksNum);
|
||||
|
||||
// testing: getNHashesEndWith(byte[], long)
|
||||
|
||||
block = blocks.get(8003);
|
||||
List<byte[]> hashList = indexedBlockStore.getNHashesEndWith(block.getHash(), 100);
|
||||
for (int i = 0; i < 100; ++i){
|
||||
block = blocks.get(8003 - i);
|
||||
String hash = Hex.toHexString(hashList.get(i));
|
||||
String hash_ = Hex.toHexString( block.getHash() );
|
||||
assertEquals(hash_, hash);
|
||||
}
|
||||
|
||||
// testing: getNHashesStartWith(long, long)
|
||||
|
||||
block = blocks.get(7003);
|
||||
hashList = indexedBlockStore.getNHashesStartWith(block.getNumber(), 100);
|
||||
for (int i = 0; i < 100; ++i){
|
||||
block = blocks.get(7003 + i);
|
||||
String hash = Hex.toHexString(hashList.get(i));
|
||||
String hash_ = Hex.toHexString( block.getHash() );
|
||||
assertEquals(hash_, hash);
|
||||
}
|
||||
|
||||
blocksDB.close();
|
||||
db.close();
|
||||
|
||||
// testing after: REOPEN
|
||||
|
||||
db = createMapDB(testDir);
|
||||
indexDB = createIndexMap(db);
|
||||
|
||||
blocksDB = new LevelDbDataSource("blocks");
|
||||
blocksDB.init();
|
||||
|
||||
indexedBlockStore = new IndexedBlockStore();
|
||||
indexedBlockStore.init(indexDB, blocksDB, null);
|
||||
|
||||
// testing: getNHashesStartWith(long, long)
|
||||
|
||||
block = blocks.get(7003);
|
||||
hashList = indexedBlockStore.getNHashesStartWith(block.getNumber(), 100);
|
||||
for (int i = 0; i < 100; ++i){
|
||||
block = blocks.get(7003 + i);
|
||||
String hash = Hex.toHexString(hashList.get(i));
|
||||
String hash_ = Hex.toHexString( block.getHash() );
|
||||
assertEquals(hash_, hash);
|
||||
}
|
||||
|
||||
FileUtil.recursiveDelete(testDir);
|
||||
}
|
||||
|
||||
@Test // cache + leveldb + mapdb, save part to disk part to cache, and check it exist
|
||||
public void test5() throws IOException {
|
||||
|
||||
BigInteger bi = new BigInteger(32, new Random());
|
||||
String testDir = "test_db_" + bi;
|
||||
SystemProperties.CONFIG.setDataBaseDir(testDir);
|
||||
|
||||
DB db = createMapDB(testDir);
|
||||
Map<Long, List<IndexedBlockStore.BlockInfo>> indexDB = createIndexMap(db);
|
||||
|
||||
KeyValueDataSource blocksDB = new LevelDbDataSource("blocks");
|
||||
blocksDB.init();
|
||||
|
||||
try {
|
||||
|
||||
IndexedBlockStore cache = new IndexedBlockStore();
|
||||
cache.init(new HashMap<Long, List<IndexedBlockStore.BlockInfo>>(), new HashMapDB(), null);
|
||||
|
||||
IndexedBlockStore indexedBlockStore = new IndexedBlockStore();
|
||||
indexedBlockStore.init(indexDB, blocksDB, cache);
|
||||
|
||||
|
||||
BigInteger cummDiff = BigInteger.ZERO;
|
||||
int preloadSize = blocks.size() / 2;
|
||||
for (int i = 0; i < preloadSize; ++i){
|
||||
Block block = blocks.get(i);
|
||||
cummDiff = cummDiff.add( block.getCumulativeDifficulty() );
|
||||
indexedBlockStore.addBlock(block, cummDiff, true);
|
||||
}
|
||||
|
||||
indexedBlockStore.flush();
|
||||
|
||||
for (int i = preloadSize; i < blocks.size(); ++i){
|
||||
Block block = blocks.get(i);
|
||||
cummDiff = cummDiff.add( block.getCumulativeDifficulty() );
|
||||
indexedBlockStore.addBlock(block, cummDiff, true);
|
||||
}
|
||||
|
||||
// testing: getTotalDifficulty()
|
||||
// testing: getMaxNumber()
|
||||
|
||||
long bestIndex = blocks.get(blocks.size() - 1).getNumber();
|
||||
assertEquals(bestIndex, indexedBlockStore.getMaxNumber());
|
||||
assertEquals(cumDifficulty, indexedBlockStore.getTotalDifficulty());
|
||||
|
||||
// testing: getBlockByHash(byte[])
|
||||
|
||||
Block block = blocks.get(50);
|
||||
Block block_ = indexedBlockStore.getBlockByHash(block.getHash());
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(150);
|
||||
block_ = indexedBlockStore.getBlockByHash(block.getHash());
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(0);
|
||||
block_ = indexedBlockStore.getBlockByHash(block.getHash());
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(8003);
|
||||
block_ = indexedBlockStore.getBlockByHash(block.getHash());
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block_ = indexedBlockStore.getBlockByHash(Hex.decode("00112233"));
|
||||
assertEquals(null, block_);
|
||||
|
||||
// testing: getChainBlockByNumber(long)
|
||||
|
||||
block = blocks.get(50);
|
||||
block_ = indexedBlockStore.getChainBlockByNumber(block.getNumber());
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(150);
|
||||
block_ = indexedBlockStore.getChainBlockByNumber(block.getNumber());
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(0);
|
||||
block_ = indexedBlockStore.getChainBlockByNumber(block.getNumber());
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(8003);
|
||||
block_ = indexedBlockStore.getChainBlockByNumber(block.getNumber());
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block_ = indexedBlockStore.getChainBlockByNumber(10000);
|
||||
assertEquals(null, block_);
|
||||
|
||||
// testing: getBlocksByNumber(long)
|
||||
|
||||
block = blocks.get(50);
|
||||
block_ = indexedBlockStore.getBlocksByNumber(block.getNumber()).get(0);
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(150);
|
||||
block_ = indexedBlockStore.getBlocksByNumber(block.getNumber()).get(0);
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(0);
|
||||
block_ = indexedBlockStore.getBlocksByNumber(block.getNumber()).get(0);
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
block = blocks.get(8003);
|
||||
block_ = indexedBlockStore.getBlocksByNumber(block.getNumber()).get(0);
|
||||
assertEquals(block.getNumber(), block_.getNumber());
|
||||
|
||||
int blocksNum = indexedBlockStore.getBlocksByNumber(10000).size();
|
||||
assertEquals(0, blocksNum);
|
||||
|
||||
// testing: getNHashesEndWith(byte[], long)
|
||||
|
||||
block = blocks.get(8003);
|
||||
List<byte[]> hashList = indexedBlockStore.getNHashesEndWith(block.getHash(), 100);
|
||||
for (int i = 0; i < 100; ++i){
|
||||
block = blocks.get(8003 - i);
|
||||
String hash = Hex.toHexString(hashList.get(i));
|
||||
String hash_ = Hex.toHexString( block.getHash() );
|
||||
assertEquals(hash_, hash);
|
||||
}
|
||||
|
||||
// testing: getNHashesStartWith(long, long)
|
||||
|
||||
block = blocks.get(7003);
|
||||
hashList = indexedBlockStore.getNHashesStartWith(block.getNumber(), 100);
|
||||
for (int i = 0; i < 100; ++i){
|
||||
block = blocks.get(7003 + i);
|
||||
String hash = Hex.toHexString(hashList.get(i));
|
||||
String hash_ = Hex.toHexString( block.getHash() );
|
||||
assertEquals(hash_, hash);
|
||||
}
|
||||
|
||||
|
||||
indexedBlockStore.flush();
|
||||
blocksDB.close();
|
||||
db.close();
|
||||
|
||||
// testing after: REOPEN
|
||||
|
||||
db = createMapDB(testDir);
|
||||
indexDB = createIndexMap(db);
|
||||
|
||||
blocksDB = new LevelDbDataSource("blocks");
|
||||
blocksDB.init();
|
||||
|
||||
indexedBlockStore = new IndexedBlockStore();
|
||||
indexedBlockStore.init(indexDB, blocksDB, null);
|
||||
|
||||
|
||||
// testing: getNHashesStartWith(long, long)
|
||||
|
||||
block = blocks.get(7003);
|
||||
hashList = indexedBlockStore.getNHashesStartWith(block.getNumber(), 100);
|
||||
for (int i = 0; i < 100; ++i){
|
||||
block = blocks.get(7003 + i);
|
||||
String hash = Hex.toHexString(hashList.get(i));
|
||||
String hash_ = Hex.toHexString( block.getHash() );
|
||||
assertEquals(hash_, hash);
|
||||
}
|
||||
} finally {
|
||||
blocksDB.close();
|
||||
db.close();
|
||||
FileUtil.recursiveDelete(testDir);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
Loading…
Reference in New Issue