BlockChain refactoring:
+ keep only index of block hash numbers in the cach + for the full block data, query DB
This commit is contained in:
parent
b3bf0f024c
commit
bb8291457a
|
@ -78,7 +78,7 @@ public class Block {
|
||||||
|
|
||||||
private void parseRLP() {
|
private void parseRLP() {
|
||||||
|
|
||||||
RLPList params = (RLPList) RLP.decode2(rlpEncoded);
|
RLPList params = RLP.decode2(rlpEncoded);
|
||||||
RLPList block = (RLPList) params.get(0);
|
RLPList block = (RLPList) params.get(0);
|
||||||
|
|
||||||
// Parse Header
|
// Parse Header
|
||||||
|
|
|
@ -10,6 +10,7 @@ import org.slf4j.LoggerFactory;
|
||||||
import org.spongycastle.util.encoders.Hex;
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static org.ethereum.core.Denomination.*;
|
import static org.ethereum.core.Denomination.*;
|
||||||
|
@ -21,7 +22,7 @@ import static org.ethereum.core.Denomination.*;
|
||||||
* Created on: 20/05/2014 10:44
|
* Created on: 20/05/2014 10:44
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class Blockchain extends ArrayList<Block> {
|
public class Blockchain {
|
||||||
|
|
||||||
private static final long serialVersionUID = -143590724563460486L;
|
private static final long serialVersionUID = -143590724563460486L;
|
||||||
|
|
||||||
|
@ -36,6 +37,10 @@ public class Blockchain extends ArrayList<Block> {
|
||||||
private long gasPrice = 1000;
|
private long gasPrice = 1000;
|
||||||
private Block lastBlock;
|
private Block lastBlock;
|
||||||
|
|
||||||
|
// keep the index of the chain for
|
||||||
|
// convenient usage, <block_number, block_hash>
|
||||||
|
private HashMap<Long, byte[]> index = new HashMap<Long, byte[]>();
|
||||||
|
|
||||||
// This map of transaction designed
|
// This map of transaction designed
|
||||||
// to approve the tx by external trusted peer
|
// to approve the tx by external trusted peer
|
||||||
private Map<String, WalletTransaction> walletTransactions =
|
private Map<String, WalletTransaction> walletTransactions =
|
||||||
|
@ -51,6 +56,16 @@ public class Blockchain extends ArrayList<Block> {
|
||||||
return lastBlock;
|
return lastBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getSize(){
|
||||||
|
return index.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Block getByNumber(int rowIndex){
|
||||||
|
byte[] parentHash = index.get((long)rowIndex);
|
||||||
|
if (parentHash == null) return null;
|
||||||
|
return new Block(db.get(parentHash));
|
||||||
|
}
|
||||||
|
|
||||||
public void addBlocks(List<Block> blocks) {
|
public void addBlocks(List<Block> blocks) {
|
||||||
|
|
||||||
if (blocks.isEmpty())
|
if (blocks.isEmpty())
|
||||||
|
@ -60,15 +75,14 @@ public class Blockchain extends ArrayList<Block> {
|
||||||
|
|
||||||
// if it is the first block to add
|
// if it is the first block to add
|
||||||
// check that the parent is the genesis
|
// check that the parent is the genesis
|
||||||
if (this.isEmpty()
|
if (index.isEmpty()
|
||||||
&& !Arrays.equals(StaticMessages.GENESIS_HASH,
|
&& !Arrays.equals(StaticMessages.GENESIS_HASH,
|
||||||
firstBlockToAdd.getParentHash())) {
|
firstBlockToAdd.getParentHash())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// if there is some blocks already keep chain continuity
|
// if there is some blocks already keep chain continuity
|
||||||
if (!this.isEmpty()) {
|
if (!index.isEmpty()) {
|
||||||
Block lastBlock = this.get(this.size() - 1);
|
String hashLast = Hex.toHexString(getLastBlock().getHash());
|
||||||
String hashLast = Hex.toHexString(lastBlock.getHash());
|
|
||||||
String blockParentHash = Hex.toHexString(firstBlockToAdd.getParentHash());
|
String blockParentHash = Hex.toHexString(firstBlockToAdd.getParentHash());
|
||||||
if (!hashLast.equals(blockParentHash)) return;
|
if (!hashLast.equals(blockParentHash)) return;
|
||||||
}
|
}
|
||||||
|
@ -87,7 +101,7 @@ public class Blockchain extends ArrayList<Block> {
|
||||||
removeWalletTransaction(tx);
|
removeWalletTransaction(tx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
logger.info("*** Block chain size: [ {} ]", this.size());
|
logger.info("*** Block chain size: [ {} ]", index.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addBlock(Block block) {
|
private void addBlock(Block block) {
|
||||||
|
@ -97,9 +111,10 @@ public class Blockchain extends ArrayList<Block> {
|
||||||
// on this price will use default 10000000000000
|
// on this price will use default 10000000000000
|
||||||
// todo: refactor this longValue some constant defaults class 10000000000000L
|
// todo: refactor this longValue some constant defaults class 10000000000000L
|
||||||
this.gasPrice = block.isGenesis() ? INITIAL_MIN_GAS_PRICE : block.getMinGasPrice();
|
this.gasPrice = block.isGenesis() ? INITIAL_MIN_GAS_PRICE : block.getMinGasPrice();
|
||||||
if(lastBlock == null || block.getNumber() > lastBlock.getNumber())
|
if(lastBlock == null || block.getNumber() > lastBlock.getNumber()){
|
||||||
this.lastBlock = block;
|
this.lastBlock = block;
|
||||||
this.add(block);
|
index.put(block.getNumber(), block.getParentHash());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,7 +150,7 @@ public class Blockchain extends ArrayList<Block> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getLatestBlockHash(){
|
public byte[] getLatestBlockHash(){
|
||||||
if (this.isEmpty())
|
if (index.isEmpty())
|
||||||
return StaticMessages.GENESIS_HASH;
|
return StaticMessages.GENESIS_HASH;
|
||||||
else
|
else
|
||||||
return lastBlock.getHash();
|
return lastBlock.getHash();
|
||||||
|
|
|
@ -74,9 +74,9 @@ public class BlockChainTable extends JFrame {
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
|
||||||
if (MainData.instance.getBlockchain().size() - 1 < lastFindIndex) return;
|
if (MainData.instance.getBlockchain().getSize() - 1 < lastFindIndex) return;
|
||||||
|
|
||||||
Block block = MainData.instance.getBlockchain().get(lastFindIndex);
|
Block block = MainData.instance.getBlockchain().getByNumber(lastFindIndex);
|
||||||
StringSelection stsel = new StringSelection(block.toString());
|
StringSelection stsel = new StringSelection(block.toString());
|
||||||
Clipboard system = Toolkit.getDefaultToolkit().getSystemClipboard();
|
Clipboard system = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||||
system.setContents(stsel,stsel);
|
system.setContents(stsel,stsel);
|
||||||
|
@ -96,10 +96,10 @@ public class BlockChainTable extends JFrame {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = lastFindIndex + 1; i < MainData.instance.getBlockchain().size(); ++i) {
|
for (int i = lastFindIndex + 1; i < MainData.instance.getBlockchain().getSize(); ++i) {
|
||||||
|
|
||||||
if (MainData.instance.getBlockchain().size() - 1 < i) return;
|
if (MainData.instance.getBlockchain().getSize() - 1 < i) return;
|
||||||
Block block = MainData.instance.getBlockchain().get(i);
|
Block block = MainData.instance.getBlockchain().getByNumber(i);
|
||||||
boolean found = block.toString().toLowerCase().contains(toFind.toLowerCase());
|
boolean found = block.toString().toLowerCase().contains(toFind.toLowerCase());
|
||||||
if (found) {
|
if (found) {
|
||||||
// todo: now we find the first occur
|
// todo: now we find the first occur
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.ethereum.gui;
|
package org.ethereum.gui;
|
||||||
|
|
||||||
|
import org.ethereum.core.Block;
|
||||||
import org.ethereum.manager.MainData;
|
import org.ethereum.manager.MainData;
|
||||||
|
|
||||||
import javax.swing.table.AbstractTableModel;
|
import javax.swing.table.AbstractTableModel;
|
||||||
|
@ -15,7 +16,7 @@ public class BlockTableModel extends AbstractTableModel {
|
||||||
public int getRowCount() {
|
public int getRowCount() {
|
||||||
|
|
||||||
fireTableDataChanged();
|
fireTableDataChanged();
|
||||||
int rowCount = MainData.instance.getBlockchain().size();
|
int rowCount = MainData.instance.getBlockchain().getSize();
|
||||||
return rowCount;
|
return rowCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,6 +31,9 @@ public class BlockTableModel extends AbstractTableModel {
|
||||||
// byte[] hash = MainData.instance.getAllBlocks().get(rowIndex).getHash();
|
// byte[] hash = MainData.instance.getAllBlocks().get(rowIndex).getHash();
|
||||||
// return Hex.toHexString(hash);
|
// return Hex.toHexString(hash);
|
||||||
|
|
||||||
return MainData.instance.getBlockchain().get(rowIndex).toString();
|
Block block = MainData.instance.getBlockchain().getByNumber(rowIndex);
|
||||||
|
if (block == null) return "";
|
||||||
|
|
||||||
|
return block.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package org.ethereum.manager;
|
||||||
|
|
||||||
import org.ethereum.core.AccountState;
|
import org.ethereum.core.AccountState;
|
||||||
import org.ethereum.core.Block;
|
import org.ethereum.core.Block;
|
||||||
import org.ethereum.core.Blockchain;
|
|
||||||
import org.ethereum.core.Transaction;
|
import org.ethereum.core.Transaction;
|
||||||
import org.ethereum.crypto.HashUtil;
|
import org.ethereum.crypto.HashUtil;
|
||||||
import org.ethereum.db.Database;
|
import org.ethereum.db.Database;
|
||||||
|
|
|
@ -359,6 +359,7 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
|
||||||
|
|
||||||
byte[] hash = MainData.instance.getBlockchain().getLatestBlockHash();
|
byte[] hash = MainData.instance.getBlockchain().getLatestBlockHash();
|
||||||
GetChainMessage chainMessage = new GetChainMessage((byte)100, hash);
|
GetChainMessage chainMessage = new GetChainMessage((byte)100, hash);
|
||||||
|
chainMessage.toString();
|
||||||
|
|
||||||
ByteBuf buffer = ctx.alloc().buffer(chainMessage.getPayload().length + 8);
|
ByteBuf buffer = ctx.alloc().buffer(chainMessage.getPayload().length + 8);
|
||||||
buffer.writeBytes(StaticMessages.MAGIC_PACKET);
|
buffer.writeBytes(StaticMessages.MAGIC_PACKET);
|
||||||
|
|
|
@ -34,6 +34,7 @@ public class GetChainMessage extends Message {
|
||||||
encodedElements[0] = new byte[]{0x14};
|
encodedElements[0] = new byte[]{0x14};
|
||||||
int i = 1;
|
int i = 1;
|
||||||
for (byte[] hash : blockHashList){
|
for (byte[] hash : blockHashList){
|
||||||
|
this.blockHashList.add(hash);
|
||||||
byte[] element = RLP.encodeElement(hash);
|
byte[] element = RLP.encodeElement(hash);
|
||||||
encodedElements[i] = element;
|
encodedElements[i] = element;
|
||||||
++i;
|
++i;
|
||||||
|
@ -41,6 +42,8 @@ public class GetChainMessage extends Message {
|
||||||
encodedElements[i] = RLP.encodeByte(number);
|
encodedElements[i] = RLP.encodeByte(number);
|
||||||
|
|
||||||
this.payload = RLP.encodeList(encodedElements);
|
this.payload = RLP.encodeList(encodedElements);
|
||||||
|
this.parsed = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -8,7 +8,7 @@ log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||||
log4j.appender.stdout.layout.ConversionPattern= %d{HH:mm:ss} [%c{1}] %m%n
|
log4j.appender.stdout.layout.ConversionPattern= %d{HH:mm:ss} [%c{1}] %m%n
|
||||||
|
|
||||||
# filter noisy classes
|
# filter noisy classes
|
||||||
log4j.logger.org.ethereum.net = FATAL
|
log4j.logger.org.ethereum.net = INFO
|
||||||
log4j.logger.org.ethereum.net.peerdiscovery = WARN
|
log4j.logger.org.ethereum.net.peerdiscovery = WARN
|
||||||
log4j.logger.java.nio = WARN
|
log4j.logger.java.nio = WARN
|
||||||
log4j.logger.io.netty = FATAL
|
log4j.logger.io.netty = FATAL
|
||||||
|
|
|
@ -16,8 +16,8 @@ peer.discovery.port = 30303
|
||||||
# that is the peer through
|
# that is the peer through
|
||||||
# we get the chain: [54.201.28.117] port: [30303]
|
# we get the chain: [54.201.28.117] port: [30303]
|
||||||
# ZeroGox
|
# ZeroGox
|
||||||
peer.active.ip = 54.204.10.41
|
#peer.active.ip = 54.204.10.41
|
||||||
peer.active.port = 30303
|
#peer.active.port = 30303
|
||||||
|
|
||||||
# Some dude in Canada
|
# Some dude in Canada
|
||||||
#peer.active.ip = 131.104.247.135
|
#peer.active.ip = 131.104.247.135
|
||||||
|
@ -29,8 +29,8 @@ peer.active.port = 30303
|
||||||
|
|
||||||
|
|
||||||
# RomanJ general
|
# RomanJ general
|
||||||
#peer.active.ip = 54.211.14.10
|
peer.active.ip = 54.211.14.10
|
||||||
#peer.active.port = 50505
|
peer.active.port = 50505
|
||||||
|
|
||||||
#peer.active.ip = 151.64.223.120
|
#peer.active.ip = 151.64.223.120
|
||||||
#peer.active.port = 30304
|
#peer.active.port = 30304
|
||||||
|
|
Loading…
Reference in New Issue