Skip to content

Commit

Permalink
Address history, probably
Browse files Browse the repository at this point in the history
  • Loading branch information
fireduck64 committed Jun 24, 2018
1 parent 753e050 commit 8648ac8
Show file tree
Hide file tree
Showing 10 changed files with 174 additions and 6 deletions.
2 changes: 2 additions & 0 deletions lib/src/Globals.java
Expand Up @@ -44,6 +44,8 @@ public class Globals

public static final int BLOCK_CHUNK_HEADER_DOWNLOAD_SIZE = 500;

public static final int ADDRESS_HISTORY_MAX_REPLY = 10000;

public static void addCryptoProvider()
{
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
Expand Down
12 changes: 12 additions & 0 deletions lib/src/db/DB.java
Expand Up @@ -28,10 +28,14 @@ public abstract class DB implements DBFace
protected DBMap block_height_map;
protected DBMap special_map;
protected ProtoDBMap<Transaction> tx_map;
protected DBMapMutationSet address_history_map;

private Config config;

public DB(Config config)
{
Runtime.getRuntime().addShutdownHook(new DBShutdownThread());
this.config = config;
}


Expand All @@ -49,6 +53,11 @@ public void open()
utxo_node_map = openMap("u");
block_height_map = openMap("height");
special_map = openMap("special");

if (config.getBoolean("addr_index"))
{
address_history_map = openMutationMapSet("addr_hist");
}
}

@Override
Expand All @@ -66,6 +75,9 @@ public void open()
@Override
public DBMap getUtxoNodeMap() { return utxo_node_map; }

@Override
public DBMapMutationSet getAddressHistoryMap() { return address_history_map; }

@Override
public ChainHash getBlockHashAtHeight(int height)
{
Expand Down
1 change: 1 addition & 0 deletions lib/src/db/DBFace.java
Expand Up @@ -10,6 +10,7 @@ public interface DBFace
public ProtoDBMap<Block> getBlockMap();
public ProtoDBMap<BlockSummary> getBlockSummaryMap();
public ProtoDBMap<Transaction> getTransactionMap();
public DBMapMutationSet getAddressHistoryMap();

public DBMap getUtxoNodeMap();

Expand Down
15 changes: 12 additions & 3 deletions lib/src/db/DBMapMutationSet.java
Expand Up @@ -6,23 +6,32 @@
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.List;
import com.google.common.collect.TreeMultimap;
import snowblossom.lib.trie.ByteStringComparator;

public abstract class DBMapMutationSet
{
public abstract void add(ByteString key, ByteString value);

public static TreeMultimap<ByteString, ByteString> createMap()
{
return TreeMultimap.create(new ByteStringComparator(), new ByteStringComparator());
}

/** Override this if the DB can do something better */
public void addAll(Collection<Map.Entry<ByteString, ByteString> > lst)
public void addAll(TreeMultimap<ByteString, ByteString> map)
{
long t1 = System.nanoTime();
for(Map.Entry<ByteString, ByteString> me : lst)

for(Map.Entry<ByteString, ByteString> me : map.entries())
{
add(me.getKey(), me.getValue());
}
TimeRecord.record(t1, "db_putmutset_seq");
}

public abstract Set<ByteString> getSet(ByteString key, int max_reply);
public abstract List<ByteString> getSet(ByteString key, int max_reply);

public abstract void remove(ByteString key, ByteString value);

Expand Down
32 changes: 30 additions & 2 deletions lib/src/db/rocksdb/RocksDBMapMutationSet.java
@@ -1,14 +1,19 @@
package snowblossom.lib.db.rocksdb;

import com.google.protobuf.ByteString;
import com.google.common.collect.TreeMultimap;
import snowblossom.lib.db.DBMapMutationSet;
import snowblossom.lib.db.DBTooManyResultsException;
import org.rocksdb.RocksDB;
import org.rocksdb.RocksDBException;
import org.rocksdb.WriteBatch;
import org.rocksdb.RocksIterator;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.LinkedList;
import java.util.List;

public class RocksDBMapMutationSet extends DBMapMutationSet
{
Expand Down Expand Up @@ -78,6 +83,29 @@ public void add(ByteString key, ByteString value)

}

@Override
public void addAll(TreeMultimap<ByteString, ByteString> map)
{
try
{
WriteBatch batch = new WriteBatch();
byte b[]=new byte[0];

for(Map.Entry<ByteString, ByteString> me : map.entries())
{
ByteString w = getDBKey(me.getKey(), me.getValue());
batch.put(w.toByteArray(), b);
}

db.write(jdb.getWriteOption(), batch);
}
catch(RocksDBException e)
{
throw new RuntimeException(e);
}

}

@Override
public void remove(ByteString key, ByteString value)
{
Expand All @@ -93,11 +121,11 @@ public void remove(ByteString key, ByteString value)
}

@Override
public Set<ByteString> getSet(ByteString key, int max_reply)
public List<ByteString> getSet(ByteString key, int max_reply)
{
ByteString dbKey = getDBKey(key);

HashSet<ByteString> set = new HashSet<>();
LinkedList<ByteString> set = new LinkedList<>();
int count = 0;
RocksIterator it = db.newIterator();

Expand Down
84 changes: 84 additions & 0 deletions node/src/AddressHistoryUtil.java
@@ -0,0 +1,84 @@
package snowblossom.node;
import snowblossom.lib.db.DB;
import snowblossom.proto.*;
import com.google.protobuf.ByteString;
import com.google.common.collect.TreeMultimap;
import snowblossom.lib.db.DBMapMutationSet;
import snowblossom.lib.*;
import java.nio.ByteBuffer;
import java.util.List;

public class AddressHistoryUtil
{
public static void saveAddressHistory(Block blk, DB db)
{
TreeMultimap<ByteString, ByteString> map = DBMapMutationSet.createMap();
int height = blk.getHeader().getBlockHeight();

for(Transaction tx : blk.getTransactionsList())
{
ChainHash tx_id = new ChainHash(tx.getTxHash());
ByteString val = getValue(tx_id, height);
TransactionInner inner = TransactionUtil.getInner(tx);

for(TransactionInput in : inner.getInputsList())
{
ByteString addr = in.getSpecHash();
map.put(addr, val);
}
for(TransactionOutput out : inner.getOutputsList())
{
ByteString addr = out.getRecipientSpecHash();
map.put(addr, val);
}

}
db.getAddressHistoryMap().addAll(map);

}

public static ByteString getValue(ChainHash tx_id, int height)
{
byte[] buff = new byte[4 + Globals.BLOCKCHAIN_HASH_LEN];

ByteBuffer bb = ByteBuffer.wrap(buff);
bb.putInt(height);
bb.put(tx_id.toByteArray());

return ByteString.copyFrom(buff);

}


public static HistoryList getHistory(AddressSpecHash spec_hash, DB db)
{
List<ByteString> value_set = db.getAddressHistoryMap().getSet(spec_hash.getBytes(), Globals.ADDRESS_HISTORY_MAX_REPLY);

HistoryList.Builder hist_list = HistoryList.newBuilder();

for(ByteString val : value_set)
{
ByteBuffer bb = ByteBuffer.wrap(val.toByteArray());
int height = bb.getInt();

byte[] b = new byte[Globals.BLOCKCHAIN_HASH_LEN];
bb.get(b);

ChainHash tx_hash = new ChainHash(b);

hist_list.addEntries(HistoryEntry
.newBuilder()
.setBlockHeight(height)
.setTxHash(tx_hash.getBytes())
.build());
}

return hist_list.build();




}


}
9 changes: 9 additions & 0 deletions node/src/BlockIngestor.java
Expand Up @@ -39,6 +39,7 @@ public class BlockIngestor
private TimeRecord time_record;

private boolean tx_index=false;
private boolean addr_index=false;

public BlockIngestor(SnowBlossomNode node)
throws Exception
Expand All @@ -63,6 +64,7 @@ public BlockIngestor(SnowBlossomNode node)
}

tx_index = node.getConfig().getBoolean("tx_index");
addr_index = node.getConfig().getBoolean("addr_index");

}

Expand Down Expand Up @@ -121,6 +123,13 @@ public boolean ingestBlock(Block blk)
db.getTransactionMap().putAll(tx_map);
}
}
if (addr_index)
{
try(TimeRecordAuto tra_tx = TimeRecord.openAuto("BlockIngestor.saveAddrHist"))
{
AddressHistoryUtil.saveAddressHistory(blk, db);
}
}


try(TimeRecordAuto tra_tx = TimeRecord.openAuto("BlockIngestor.blockSave"))
Expand Down
5 changes: 4 additions & 1 deletion node/src/Peerage.java
Expand Up @@ -127,7 +127,10 @@ private PeerChainTip getTip()
}
for(int i=0; i<10; i++)
{
tip.addPeers(shuffled_peer_list.poll());
if (shuffled_peer_list.size() > 0)
{
tip.addPeers(shuffled_peer_list.poll());
}
}

return tip.build();
Expand Down
10 changes: 10 additions & 0 deletions node/src/SnowUserService.java
Expand Up @@ -274,6 +274,16 @@ public void getMempoolTransactionList(RequestAddress req, StreamObserver<Transac
observer.onCompleted();
}

@Override
public void getAddressHistory(RequestAddress req, StreamObserver<HistoryList> observer)
{
AddressSpecHash spec_hash = new AddressSpecHash(req.getAddressSpecHash());

observer.onNext( AddressHistoryUtil.getHistory(spec_hash, node.getDB()) );
observer.onCompleted();

}


class BlockSubscriberInfo
{
Expand Down
10 changes: 10 additions & 0 deletions protolib/snowblossom.proto
Expand Up @@ -146,6 +146,7 @@ service UserService {
rpc SubmitTransaction ( Transaction ) returns ( SubmitReply ) {}
rpc GetUTXONode( GetUTXONodeRequest ) returns ( GetUTXONodeReply ) {}
rpc GetMempoolTransactionList ( RequestAddress ) returns ( TransactionHashList ) {}
rpc GetAddressHistory ( RequestAddress ) returns ( HistoryList ) {}

rpc GetNodeStatus ( NullRequest ) returns ( NodeStatus ) {}
rpc GetBlock ( RequestBlock ) returns ( Block ) {}
Expand Down Expand Up @@ -241,6 +242,15 @@ message TransactionHashList {
repeated bytes tx_hashes = 1;
}

message HistoryList {
repeated HistoryEntry entries = 1;
}
message HistoryEntry {
int32 block_height = 1;
bytes tx_hash = 2;
}


message NullRequest {

}
Expand Down

0 comments on commit 8648ac8

Please sign in to comment.