Reduced genesis block load time.
This commit is contained in:
parent
502ec0b9b1
commit
cde1454b85
|
@ -231,13 +231,35 @@ public class EthereumRemoteService extends EthereumService {
|
|||
if (ethereum != null) {
|
||||
System.out.println("Loading genesis");
|
||||
broadcastEvent(EventFlag.EVENT_TRACE, new TraceEventData("Loading genesis block. This may take a few minutes..."));
|
||||
/*
|
||||
String genesisFile = CONFIG.genesisInfo();
|
||||
long startTime = System.nanoTime();
|
||||
try {
|
||||
InputStream is = getApplication().getAssets().open("genesis/" + genesisFile);
|
||||
Genesis.androidGetInstance(is);
|
||||
InputStream genesis = getApplication().getAssets().open("genesis/" + genesisFile);
|
||||
Genesis.androidGetInstance(genesis);
|
||||
genesis.close();
|
||||
} catch (Exception e) {
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
long endTime = System.nanoTime();
|
||||
System.out.println((endTime - startTime)/1000000);
|
||||
Genesis.reset();
|
||||
*/
|
||||
long startTime1 = System.nanoTime();
|
||||
try {
|
||||
InputStream genesis = getApplication().getAssets().open("genesis/genesis.bin");
|
||||
InputStream premine = getApplication().getAssets().open("genesis/premine.bin");
|
||||
InputStream roothash = getApplication().getAssets().open("genesis/roothash.bin");
|
||||
Genesis.binaryGetInstance(genesis, premine, roothash);
|
||||
genesis.close();
|
||||
premine.close();
|
||||
roothash.close();
|
||||
} catch (Exception e) {
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
long endTime1 = System.nanoTime();
|
||||
System.out.println((endTime1 - startTime1)/1000000);
|
||||
|
||||
System.out.println("Genesis loaded");
|
||||
if (privateKeys == null || privateKeys.size() == 0) {
|
||||
privateKeys = new ArrayList<>();
|
||||
|
|
|
@ -5,11 +5,12 @@ import org.ethereum.util.RLPList;
|
|||
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigInteger;
|
||||
|
||||
import static org.ethereum.crypto.HashUtil.*;
|
||||
|
||||
public class AccountState {
|
||||
public class AccountState implements Serializable {
|
||||
|
||||
private byte[] rlpEncoded;
|
||||
|
||||
|
|
|
@ -9,7 +9,13 @@ import org.json.simple.parser.JSONParser;
|
|||
import org.json.simple.parser.ParseException;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigInteger;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
@ -35,7 +41,7 @@ import static org.ethereum.util.ByteUtil.wrap;
|
|||
* <p>
|
||||
* See Yellow Paper: http://www.gavwood.com/Paper.pdf (Appendix I. Genesis Block)
|
||||
*/
|
||||
public class Genesis extends Block {
|
||||
public class Genesis extends Block implements Serializable {
|
||||
|
||||
private Map<ByteArrayWrapper, AccountState> premine = new HashMap<>();
|
||||
|
||||
|
@ -45,6 +51,10 @@ public class Genesis extends Block {
|
|||
|
||||
private static Block instance;
|
||||
|
||||
public Genesis(byte[] rlpEncoded) {
|
||||
super(rlpEncoded);
|
||||
}
|
||||
|
||||
public Genesis(byte[] parentHash, byte[] unclesHash, byte[] coinbase, byte[] logsBloom,
|
||||
byte[] difficulty, long number, long gasLimit,
|
||||
long gasUsed, long timestamp,
|
||||
|
@ -68,6 +78,17 @@ public class Genesis extends Block {
|
|||
return instance;
|
||||
}
|
||||
|
||||
public static void reset() {
|
||||
instance = null;
|
||||
}
|
||||
|
||||
public static Block binaryGetInstance(InputStream genesis, InputStream premine, InputStream roothash) {
|
||||
if (instance == null) {
|
||||
instance = GenesisLoader.loadBinaryGenesis(genesis, premine, roothash);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public Map<ByteArrayWrapper, AccountState> getPremine() {
|
||||
return premine;
|
||||
}
|
||||
|
@ -75,4 +96,17 @@ public class Genesis extends Block {
|
|||
public void setPremine(Map<ByteArrayWrapper, AccountState> premine) {
|
||||
this.premine = premine;
|
||||
}
|
||||
|
||||
public static byte[] serialize(Object obj) throws IOException {
|
||||
ByteArrayOutputStream b = new ByteArrayOutputStream();
|
||||
ObjectOutputStream o = new ObjectOutputStream(b);
|
||||
o.writeObject(obj);
|
||||
return b.toByteArray();
|
||||
}
|
||||
|
||||
public static Object deserialize(byte[] bytes) throws IOException, ClassNotFoundException {
|
||||
ByteArrayInputStream b = new ByteArrayInputStream(bytes);
|
||||
ObjectInputStream o = new ObjectInputStream(b);
|
||||
return o.readObject();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,15 +4,22 @@ import com.google.common.io.ByteStreams;
|
|||
import org.codehaus.jackson.map.ObjectMapper;
|
||||
import org.codehaus.jackson.type.JavaType;
|
||||
import org.ethereum.core.AccountState;
|
||||
import org.ethereum.core.Block;
|
||||
import org.ethereum.core.Genesis;
|
||||
import org.ethereum.db.ByteArrayWrapper;
|
||||
import org.ethereum.jsontestsuite.Utils;
|
||||
import org.ethereum.trie.SecureTrie;
|
||||
import org.ethereum.trie.Trie;
|
||||
import org.ethereum.util.ByteUtil;
|
||||
import org.ethereum.vm.program.Program;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.math.BigInteger;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
@ -48,6 +55,97 @@ public class GenesisLoader {
|
|||
byte[] rootHash = generateRootHash(premine);
|
||||
genesis.setStateRoot(rootHash);
|
||||
|
||||
return genesis;
|
||||
} catch (Throwable e) {
|
||||
System.err.print(e.getMessage());
|
||||
System.err.println("Genesis block configuration is corrupted or not found ./resources/genesis/...");
|
||||
System.exit(-1);
|
||||
}
|
||||
System.err.println("Genesis block configuration is corrupted or not found ./resources/genesis/...");
|
||||
System.exit(-1);
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void exportGenesis(Genesis genesis) {
|
||||
try {
|
||||
byte[] data = genesis.getEncoded();
|
||||
FileOutputStream fos = new FileOutputStream("genesis.bin");
|
||||
fos.write(data, 0, data.length);
|
||||
fos.flush();
|
||||
fos.close();
|
||||
|
||||
ByteArrayOutputStream b = new ByteArrayOutputStream();
|
||||
ObjectOutputStream o = new ObjectOutputStream(b);
|
||||
o.writeObject(genesis.getPremine());
|
||||
byte[] data1 = b.toByteArray();
|
||||
FileOutputStream fos1 = new FileOutputStream("premine.bin");
|
||||
fos1.write(data1, 0, data1.length);
|
||||
fos1.flush();
|
||||
fos1.close();
|
||||
|
||||
|
||||
FileOutputStream fos2 = new FileOutputStream("roothash.bin");
|
||||
fos2.write(genesis.getStateRoot(), 0, genesis.getStateRoot().length);
|
||||
fos2.flush();
|
||||
fos2.close();
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static Genesis loadBinaryGenesis(InputStream genesisStream, InputStream premineStream, InputStream roothashStream) {
|
||||
|
||||
|
||||
try {
|
||||
|
||||
byte[] data = ByteStreams.toByteArray(genesisStream);
|
||||
Genesis genesis = new Genesis(data);
|
||||
|
||||
data = ByteStreams.toByteArray(premineStream);
|
||||
Map<ByteArrayWrapper, AccountState> premine = (Map<ByteArrayWrapper, AccountState>)Genesis.deserialize(data);
|
||||
genesis.setPremine(premine);
|
||||
|
||||
data = ByteStreams.toByteArray(roothashStream);
|
||||
genesis.setStateRoot(data);
|
||||
|
||||
return genesis;
|
||||
} catch (Throwable e) {
|
||||
System.err.print(e.getMessage());
|
||||
System.err.println("Genesis block configuration is corrupted or not found ./resources/genesis/...");
|
||||
System.exit(-1);
|
||||
}
|
||||
System.err.println("Genesis block configuration is corrupted or not found ./resources/genesis/...");
|
||||
System.exit(-1);
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Genesis loadBinaryGenesis() {
|
||||
|
||||
|
||||
try {
|
||||
File inputFile = new File("genesis.bin");
|
||||
byte[] data = new byte[(int)inputFile.length()];
|
||||
FileInputStream fis = new FileInputStream(inputFile);
|
||||
fis.read(data, 0, data.length);
|
||||
fis.close();
|
||||
|
||||
Genesis genesis = new Genesis(data);
|
||||
|
||||
inputFile = new File("premine.bin");
|
||||
data = new byte[(int)inputFile.length()];
|
||||
fis = new FileInputStream(inputFile);
|
||||
fis.read(data, 0, data.length);
|
||||
fis.close();
|
||||
|
||||
Map<ByteArrayWrapper, AccountState> premine = (Map<ByteArrayWrapper, AccountState>)Genesis.deserialize(data);
|
||||
genesis.setPremine(premine);
|
||||
|
||||
inputFile = new File("roothash.bin");
|
||||
data = new byte[(int)inputFile.length()];
|
||||
fis = new FileInputStream(inputFile);
|
||||
fis.read(data, 0, data.length);
|
||||
fis.close();
|
||||
genesis.setStateRoot(data);
|
||||
|
||||
return genesis;
|
||||
} catch (Throwable e) {
|
||||
|
|
|
@ -167,6 +167,7 @@ public class WorldManager {
|
|||
Set<ByteArrayWrapper> keys = genesis.getPremine().keySet();
|
||||
int size = keys.size();
|
||||
int index = 0;
|
||||
long startTime0 = System.nanoTime();
|
||||
for (ByteArrayWrapper key : keys) {
|
||||
index++;
|
||||
if (index % 500 == 0 || index == size) {
|
||||
|
@ -175,6 +176,8 @@ public class WorldManager {
|
|||
repository.createAccount(key.getData());
|
||||
repository.addBalance(key.getData(), genesis.getPremine().get(key).getBalance());
|
||||
}
|
||||
long endTime0 = System.nanoTime();
|
||||
System.out.println("Import accounts time: " + ((endTime0 - startTime0) / 1000000));
|
||||
|
||||
blockStore.saveBlock(Genesis.getInstance(), Genesis.getInstance().getCumulativeDifficulty(), true);
|
||||
|
||||
|
@ -183,7 +186,7 @@ public class WorldManager {
|
|||
blockStore.flush();
|
||||
listener.onBlock(Genesis.getInstance(), new ArrayList<TransactionReceipt>());
|
||||
repository.dumpState(Genesis.getInstance(), 0, 0, null);
|
||||
|
||||
repository.flush();
|
||||
|
||||
logger.info("Genesis block imported");
|
||||
} else {
|
||||
|
|
|
@ -55,8 +55,6 @@ public class Channel {
|
|||
|
||||
private final static Logger logger = LoggerFactory.getLogger("net");
|
||||
|
||||
ChannelManager channelManager;
|
||||
|
||||
private MessageQueue msgQueue;
|
||||
|
||||
private P2pHandler p2pHandler;
|
||||
|
@ -81,10 +79,9 @@ public class Channel {
|
|||
private boolean discoveryMode;
|
||||
|
||||
@Inject
|
||||
public Channel(ChannelManager channelManager, MessageQueue msgQueue, P2pHandler p2pHandler
|
||||
public Channel(MessageQueue msgQueue, P2pHandler p2pHandler
|
||||
, ShhHandler shhHandler, BzzHandler bzzHandler, MessageCodec messageCodec
|
||||
, NodeManager nodeManager, EthHandlerFactory ethHandlerFactory) {
|
||||
this.channelManager = channelManager;
|
||||
this.msgQueue = msgQueue;
|
||||
this.p2pHandler = p2pHandler;
|
||||
this.shhHandler = shhHandler;
|
||||
|
|
Loading…
Reference in New Issue