package com.google.bitcoin.core;
import java.math.BigInteger;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.RelationshipType;
import org.neo4j.graphdb.index.Index;
import org.neo4j.graphdb.index.IndexHits;
import org.neo4j.graphdb.index.IndexManager;
import com.sun.org.apache.xerces.internal.impl.dv.util.HexBin;
public class GraphBlock extends StoredBlock implements Nodeable, GraphSaveable {
private Node node;
private NetworkParameters params;
protected GraphBlockHeader header;
public GraphBlock(GraphBlockHeader header, BigInteger chainWork, int height) {
super(header, chainWork, height);
this.header=header;
}
public void save(GraphDatabaseService graph){
IndexManager index=graph.index();
Index<Node> blockIndex=index.forNodes("blocks");
if(node==null){
node=graph.createNode();
}
node.setProperty("height", height);
node.setProperty("chainWork", chainWork.toByteArray());
node.setProperty("hash",header.getHash());
node.setProperty("version", header.getVersion());
node.setProperty("prevBlockHash", header.getPrevBlockHash());
node.setProperty("merkleRoot", header.getMerkleRoot());
node.setProperty("time", (int) header.getTime());
node.setProperty("difficultyTarget",header.getDifficultyTarget());
node.setProperty("nonce",header.getNonce());
blockIndex.add(node, "hash", header.getHashAsString());
blockIndex.add(node, "height", height);
for(GraphTransaction t : header.transactions){
t.createdAt=(int) header.getTime();
t.coinbaseValue=getSubsidy();
t.save(graph);
Relationship r=node.createRelationshipTo(t.node(), GraphRelationships.HAS_TRANSACTION);
r.setProperty("index",t.index);
GraphWallet.processTransaction(t);
}
}
public boolean equals(Object other) {
if (!(other instanceof GraphBlock)) return false;
GraphBlock o = (GraphBlock) other;
return o.header.equals(header) && o.chainWork.equals(chainWork) && o.height == height;
}
public GraphBlockHeader getHeader(){
return header;
}
public GraphBlock(NetworkParameters n, Node node) {
super();
params=n;
this.header=new GraphBlockHeader(params);
this.node=node;
this.chainWork=new BigInteger((byte[]) node.getProperty("chainWork"));
this.height=(Integer) node.getProperty("height");
header.setVersion( (Long) node.getProperty("version"));
header.setPrevBlockHash((byte[]) node.getProperty("prevBlockHash"));
header.setMerkleRoot((byte[]) node.getProperty("merkleRoot"));
header.setTime( (Integer) node.getProperty("time"));
header.setDifficultyTarget((Long) node.getProperty("difficultyTarget"));
header.setNonce((Long) node.getProperty("nonce"));
}
public BigInteger getSubsidy(){
return Utils.FIDDY_COIN.shiftLeft(height/210000);
}
public GraphBlock build(Block block) throws VerificationException {
// Stored blocks track total work done in this chain, because the canonical chain is the one that represents
// the largest amount of work done not the tallest.
BigInteger chainWork = this.chainWork.add(block.getWork());
int height = this.height + 1;
return new GraphBlock((GraphBlockHeader) block, chainWork, height);
}
@Override
public Node node() {
// TODO Auto-generated method stub
return node;
}
public void save(){
save(node().getGraphDatabase());
}
}