package com.google.bitcoin.core;
import java.io.FileInputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import org.ibex.nestedvm.util.Seekable.InputStream;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.RelationshipType;
import org.neo4j.graphdb.index.Index;
import org.neo4j.graphdb.index.IndexManager;
import org.neo4j.graphdb.traversal.TraversalDescription;
import org.neo4j.kernel.EmbeddedGraphDatabase;
import org.neo4j.kernel.impl.index.IndexStore;
import org.neo4j.kernel.impl.traversal.TraversalDescriptionImpl;
public class GraphBlockStore implements BlockStore {
private GraphDatabaseService graph;
private GraphBlockChainNodeAdapter graphBlockChain;
private IndexManager indexer;
private Index<Node> namedNodes;
private NetworkParameters params;
public GraphBlockStore(NetworkParameters n, String path){
Properties props = new Properties();
try
{
java.io.InputStream stream = this.getClass().getResourceAsStream("/neo4j.properties");
try
{
props.load( stream );
}
finally
{
stream.close();
}
}
catch ( Exception e )
{
throw new IllegalArgumentException( "Unable to load");
}
Set<Entry<Object,Object>> entries = props.entrySet();
Map<String,String> stringProps = new HashMap<String,String>();
for ( Entry<Object,Object> entry : entries )
{
String key = (String) entry.getKey();
String value = (String) entry.getValue();
stringProps.put( key, value );
}
graph = new EmbeddedGraphDatabase( path,stringProps );
indexer = graph.index();
params = n;
org.neo4j.graphdb.Transaction tx = graph.beginTx();
try
{
graphBlockChain = new GraphBlockChainNodeAdapter(params, graph);
tx.success();
}
finally
{
tx.finish();
}
Block genesisHeader = params.genesisBlock;
GraphBlockHeader h;
try {
h = new GraphBlockHeader(params, genesisHeader.bitcoinSerialize());
GraphBlock h2=get(h.hash);
if(h2==null){
throw new RuntimeException("can't find genesis block");
}
} catch (ProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BlockStoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
registerShutdownHook( graph );
}
@Override
public void put(GraphBlock block) throws BlockStoreException {
org.neo4j.graphdb.Transaction tx = graph.beginTx();
try
{
GraphBlock graphBlock=(GraphBlock) block;
graphBlockChain.add(graphBlock);
tx.success();
}
finally
{
tx.finish();
}
}
@Override
public GraphBlock get(byte[] hash) throws BlockStoreException {
// TODO Auto-generated method stub
return graphBlockChain.get(hash);
}
@Override
public GraphBlock getChainHead() throws BlockStoreException {
// TODO Auto-generated method stub
return graphBlockChain.getChainHead();
}
@Override
public void setChainHead(GraphBlock chainHead) throws BlockStoreException {
org.neo4j.graphdb.Transaction tx = graph.beginTx();
try
{
GraphBlock graphBlock=(GraphBlock) chainHead;
graphBlockChain.setChainHead(graphBlock);
tx.success();
}
finally
{
tx.finish();
}
}
private static void registerShutdownHook( final GraphDatabaseService graphDb )
{
// Registers a shutdown hook for the Neo4j instance so that it
// shuts down nicely when the VM exits (even if you "Ctrl-C" the
// running example before it's completed)
Runtime.getRuntime().addShutdownHook( new Thread()
{
@Override
public void run()
{
graphDb.shutdown();
}
} );
}
public GraphDatabaseService graph(){
return graph;
}
public GraphAddress findOrCreateAddress(String base58hash) throws AddressFormatException{
return GraphAddress.findOrCreateAddress(graph, params, base58hash);
}
public StoredBlock getByHeight(int i) {
Index<Node> blockIndex=indexer.forNodes("blocks");
Node n=blockIndex.get("height", i).getSingle();
if(n==null){
return null;
}
return new GraphBlock(params,n);
}
}