Merge pull request #40 from nicksavers/master
Blockchain bugfix & use generics
This commit is contained in:
commit
bc725d82e6
|
@ -181,7 +181,7 @@ public class Blockchain {
|
|||
public void loadChain() {
|
||||
DBIterator iterator = db.iterator();
|
||||
try {
|
||||
if (index.size() == 0) {
|
||||
if (!iterator.hasNext()) {
|
||||
logger.info("DB is empty - adding Genesis");
|
||||
this.lastBlock = Genesis.getInstance();
|
||||
this.addBlock(lastBlock);
|
||||
|
|
|
@ -5,6 +5,7 @@ import java.util.Iterator;
|
|||
import java.util.Map;
|
||||
|
||||
import org.ethereum.crypto.HashUtil;
|
||||
import org.ethereum.db.ByteArrayWrapper;
|
||||
import org.ethereum.util.Value;
|
||||
import org.iq80.leveldb.DB;
|
||||
|
||||
|
@ -15,13 +16,13 @@ import org.iq80.leveldb.DB;
|
|||
*/
|
||||
public class Cache {
|
||||
|
||||
private Map<byte[], Node> nodes;
|
||||
private Map<ByteArrayWrapper, Node> nodes;
|
||||
private DB db;
|
||||
private boolean isDirty;
|
||||
|
||||
public Cache(DB db) {
|
||||
this.db = db;
|
||||
nodes = new HashMap<byte[], Node>();
|
||||
nodes = new HashMap<ByteArrayWrapper, Node>();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -35,7 +36,7 @@ public class Cache {
|
|||
byte[] enc = value.encode();
|
||||
if (enc.length >= 32) {
|
||||
byte[] sha = HashUtil.sha3(enc);
|
||||
this.nodes.put(sha, new Node(value, true));
|
||||
this.nodes.put(new ByteArrayWrapper(sha), new Node(value, true));
|
||||
this.isDirty = true;
|
||||
return sha;
|
||||
}
|
||||
|
@ -43,21 +44,23 @@ public class Cache {
|
|||
}
|
||||
|
||||
public Value get(byte[] key) {
|
||||
ByteArrayWrapper keyObj = new ByteArrayWrapper(key);
|
||||
// First check if the key is the cache
|
||||
if (this.nodes.get(key) != null) {
|
||||
return this.nodes.get(key).getValue();
|
||||
if (this.nodes.get(keyObj) != null) {
|
||||
return this.nodes.get(keyObj).getValue();
|
||||
}
|
||||
// Get the key of the database instead and cache it
|
||||
byte[] data = this.db.get(key);
|
||||
Value value = new Value(data);
|
||||
// Create caching node
|
||||
this.nodes.put(key, new Node(value, false));
|
||||
this.nodes.put(keyObj, new Node(value, false));
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public void delete(byte[] key) {
|
||||
this.nodes.remove(key);
|
||||
ByteArrayWrapper keyObj = new ByteArrayWrapper(key);
|
||||
this.nodes.remove(keyObj);
|
||||
this.db.delete(key);
|
||||
}
|
||||
|
||||
|
@ -67,10 +70,10 @@ public class Cache {
|
|||
return;
|
||||
}
|
||||
|
||||
for (byte[] key : this.nodes.keySet()) {
|
||||
for (ByteArrayWrapper key : this.nodes.keySet()) {
|
||||
Node node = this.nodes.get(key);
|
||||
if (node.isDirty()) {
|
||||
this.db.put(key, node.getValue().encode());
|
||||
this.db.put(key.getData(), node.getValue().encode());
|
||||
node.setDirty(false);
|
||||
}
|
||||
}
|
||||
|
@ -79,12 +82,12 @@ public class Cache {
|
|||
// If the nodes grows beyond the 200 entries we simple empty it
|
||||
// FIXME come up with something better
|
||||
if (this.nodes.size() > 200) {
|
||||
this.nodes = new HashMap<byte[], Node>();
|
||||
this.nodes = new HashMap<ByteArrayWrapper, Node>();
|
||||
}
|
||||
}
|
||||
|
||||
public void undo() {
|
||||
Iterator<Map.Entry<byte[], Node>> iter = this.nodes.entrySet().iterator();
|
||||
Iterator<Map.Entry<ByteArrayWrapper, Node>> iter = this.nodes.entrySet().iterator();
|
||||
while (iter.hasNext()) {
|
||||
if(iter.next().getValue().isDirty()){
|
||||
iter.remove();
|
||||
|
@ -101,7 +104,7 @@ public class Cache {
|
|||
this.isDirty = isDirty;
|
||||
}
|
||||
|
||||
public Map<byte[], Node> getNodes() {
|
||||
public Map<ByteArrayWrapper, Node> getNodes() {
|
||||
return nodes;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package org.ethereum.trie;
|
||||
|
||||
import org.ethereum.db.ByteArrayWrapper;
|
||||
import org.ethereum.db.Database;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
@ -12,72 +11,68 @@ import java.util.Map;
|
|||
* @author: Roman Mandeleil
|
||||
* Created on: 11/06/2014 19:47
|
||||
*/
|
||||
|
||||
public class TrackTrie implements TrieFacade {
|
||||
|
||||
private TrieFacade trie;
|
||||
|
||||
private TrieFacade trie;
|
||||
private boolean trackingChanges;
|
||||
private Map<ByteArrayWrapper, byte[]> changes;
|
||||
private Map<ByteArrayWrapper, byte[]> deletes;
|
||||
|
||||
private boolean trackingChanges;
|
||||
private Map<ByteArrayWrapper, byte[]> changes;
|
||||
private Map<ByteArrayWrapper, byte[]> deletes;
|
||||
public TrackTrie(TrieFacade trie) {
|
||||
this.trie = trie;
|
||||
}
|
||||
|
||||
public TrackTrie(TrieFacade trie) {
|
||||
this.trie = trie ;
|
||||
}
|
||||
public void startTrack() {
|
||||
changes = new HashMap<ByteArrayWrapper, byte[]>();
|
||||
deletes = new HashMap<ByteArrayWrapper, byte[]>();
|
||||
trackingChanges = true;
|
||||
}
|
||||
|
||||
public void commitTrack() {
|
||||
for (ByteArrayWrapper key : changes.keySet()) {
|
||||
trie.update(key.getData(), changes.get(key));
|
||||
}
|
||||
changes = null;
|
||||
trackingChanges = false;
|
||||
}
|
||||
|
||||
public void startTrack(){
|
||||
changes = new HashMap<>();
|
||||
deletes = new HashMap<>();
|
||||
trackingChanges = true;
|
||||
}
|
||||
public void rollbackTrack() {
|
||||
changes = new HashMap<ByteArrayWrapper, byte[]>();
|
||||
deletes = new HashMap<ByteArrayWrapper, byte[]>();
|
||||
changes = null;
|
||||
trackingChanges = false;
|
||||
}
|
||||
|
||||
public void commitTrack(){
|
||||
for(ByteArrayWrapper key : changes.keySet()){
|
||||
trie.update(key.getData(), changes.get(key));
|
||||
}
|
||||
changes = null;
|
||||
trackingChanges = false;
|
||||
}
|
||||
@Override
|
||||
public void update(byte[] key, byte[] value) {
|
||||
if (trackingChanges) {
|
||||
changes.put(new ByteArrayWrapper(key), value);
|
||||
} else {
|
||||
trie.update(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
public void rollbackTrack(){
|
||||
changes = new HashMap<>();
|
||||
deletes = new HashMap<>();
|
||||
changes = null;
|
||||
trackingChanges = false;
|
||||
}
|
||||
@Override
|
||||
public byte[] get(byte[] key) {
|
||||
if (trackingChanges) {
|
||||
ByteArrayWrapper wKey = new ByteArrayWrapper(key);
|
||||
if (deletes.get(wKey) != null)
|
||||
return null;
|
||||
if (changes.get(wKey) != null)
|
||||
return changes.get(wKey);
|
||||
return trie.get(key);
|
||||
}
|
||||
return trie.get(key);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void update(byte[] key, byte[] value) {
|
||||
if (trackingChanges){
|
||||
changes.put( new ByteArrayWrapper(key) , value);
|
||||
} else {
|
||||
trie.update(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] get(byte[] key) {
|
||||
if(trackingChanges){
|
||||
ByteArrayWrapper wKey = new ByteArrayWrapper(key);
|
||||
if (deletes.get(wKey) != null) return null;
|
||||
if (changes.get(wKey) != null) return changes.get(wKey);
|
||||
return trie.get(key);
|
||||
}
|
||||
return trie.get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(byte[] key) {
|
||||
if (trackingChanges){
|
||||
ByteArrayWrapper wKey = new ByteArrayWrapper(key);
|
||||
deletes.put(wKey, null);
|
||||
} else {
|
||||
trie.delete(key);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void delete(byte[] key) {
|
||||
if (trackingChanges) {
|
||||
ByteArrayWrapper wKey = new ByteArrayWrapper(key);
|
||||
deletes.put(wKey, null);
|
||||
} else {
|
||||
trie.delete(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import static org.ethereum.util.CompactEncoder.*;
|
|||
import java.util.Arrays;
|
||||
|
||||
import org.ethereum.crypto.HashUtil;
|
||||
import org.ethereum.db.Database;
|
||||
import org.ethereum.db.ByteArrayWrapper;
|
||||
import org.ethereum.util.Value;
|
||||
import org.iq80.leveldb.DB;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
@ -125,7 +125,6 @@ public class Trie implements TrieFacade{
|
|||
return c.asBytes();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delete a key/value pair from the trie
|
||||
*
|
||||
|
@ -135,7 +134,6 @@ public class Trie implements TrieFacade{
|
|||
delete(Hex.encode(key));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delete a key/value pair from the trie
|
||||
*
|
||||
|
@ -375,7 +373,7 @@ public class Trie implements TrieFacade{
|
|||
// Returns a copy of this trie
|
||||
public Trie copy() {
|
||||
Trie trie = new Trie(this.cache.getDb(), this.root);
|
||||
for (byte[] key : this.cache.getNodes().keySet()) {
|
||||
for (ByteArrayWrapper key : this.cache.getNodes().keySet()) {
|
||||
Node node = this.cache.getNodes().get(key);
|
||||
trie.cache.getNodes().put(key, node.copy());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue