From c9766a58cf5f56b7b87c126379a3b8c55ea224b5 Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 14 May 2018 22:36:00 +0200 Subject: [PATCH 1/3] Json methods for Block, Blockheader, Transaction, Wallet and Context --- src/main/java/org/dilithium/core/Block.java | 7 +- .../java/org/dilithium/core/BlockHeader.java | 5 +- .../java/org/dilithium/core/Transaction.java | 110 +++++++-------- src/main/java/org/dilithium/core/Wallet.java | 63 +++++---- src/main/java/org/dilithium/db/Context.java | 126 +++++++++--------- .../java/org/dilithium/util/JsonUtil.java | 12 ++ 6 files changed, 178 insertions(+), 145 deletions(-) create mode 100644 src/main/java/org/dilithium/util/JsonUtil.java diff --git a/src/main/java/org/dilithium/core/Block.java b/src/main/java/org/dilithium/core/Block.java index aff0ce2..5e7525d 100644 --- a/src/main/java/org/dilithium/core/Block.java +++ b/src/main/java/org/dilithium/core/Block.java @@ -29,6 +29,7 @@ import org.dilithium.serialization.Serializer; import org.dilithium.util.ByteUtil; import org.dilithium.util.HashUtil; +import org.dilithium.util.JsonUtil; /** * This class @@ -139,7 +140,11 @@ public byte[] getEncoded(){ }); return encodedBlock; } - + + public String getJson(){ + return JsonUtil.getJson(this); + } + @Override public String toString(){ return header.toString(); diff --git a/src/main/java/org/dilithium/core/BlockHeader.java b/src/main/java/org/dilithium/core/BlockHeader.java index 11c5c90..f7e1241 100644 --- a/src/main/java/org/dilithium/core/BlockHeader.java +++ b/src/main/java/org/dilithium/core/BlockHeader.java @@ -27,6 +27,7 @@ import org.dilithium.serialization.Serializer; import org.dilithium.util.ByteUtil; import org.dilithium.util.Encoding; +import org.dilithium.util.JsonUtil; /** * This class @@ -246,7 +247,9 @@ public byte[] getEncoded(){ //System.out.println("header parcel length: " + parcel.length); return parcel; } - + public String getJson(){ + return JsonUtil.getJson(this); + } @Override public String toString(){ return "block-header: {\n" + diff --git a/src/main/java/org/dilithium/core/Transaction.java b/src/main/java/org/dilithium/core/Transaction.java index 95190af..d8dbcc2 100644 --- a/src/main/java/org/dilithium/core/Transaction.java +++ b/src/main/java/org/dilithium/core/Transaction.java @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2018 Dilithium Team . * * The Dilithium library is free software; you can redistribute it and/or @@ -21,21 +21,19 @@ import java.math.BigInteger; import java.security.interfaces.ECPrivateKey; + import org.dilithium.core.axiom.Axiom; import org.dilithium.serialization.ParcelData; import org.dilithium.serialization.Serializer; -import org.dilithium.util.ByteUtil; -import org.dilithium.util.Encoding; -import org.dilithium.util.HashUtil; -import org.dilithium.util.KeyUtil; +import org.dilithium.util.*; /** - * This class + * This class */ public class Transaction { - + //Transaction contents: - + /* The hash of the parcel encoded transactiions contents: nonce, value, data, receipient, sender and networkId */ private byte[] hash; /* this nonce prevents replay attacks */ @@ -48,7 +46,7 @@ public class Transaction { private final byte[] recipient; /* network id prevents replay attack by specifying the transactions network e.g. main-net, test-net or a forked network */ private final byte networkId; - /* this transactoins hash signed by the sender, concatonnated in the order r-s-v */ + /* this transactoins hash signed by the sender, concatonnated in the order r-s-v */ private final byte[] signature; /* the senders(aka the owner of the dilithium being sent) public key. (this can be salvaged from signature) */ private final byte[] sender; //Note sender should be recovered from signature, and will eventually no longer be part of the tx hash. @@ -56,14 +54,14 @@ public class Transaction { private byte[] encoded; /* this verified bool is true if transaction is actually from the owner of the balance -> signature is valid */ private boolean verified; - - + + // Constructors : - public Transaction(ECPrivateKey privateKey, BigInteger nonce, BigInteger value, byte[] data, byte[] recipient, byte networkId, byte[] sender, Axiom axiom){ - this(privateKey, ByteUtil.bigIntegerToBytes(nonce),ByteUtil.bigIntegerToBytes(value), data, recipient, networkId, sender, axiom); + public Transaction(ECPrivateKey privateKey, BigInteger nonce, BigInteger value, byte[] data, byte[] recipient, byte networkId, byte[] sender, Axiom axiom) { + this(privateKey, ByteUtil.bigIntegerToBytes(nonce), ByteUtil.bigIntegerToBytes(value), data, recipient, networkId, sender, axiom); } - - public Transaction(ECPrivateKey privateKey, byte[] nonce, byte[] value, byte[] data, byte[] recipient, byte networkId, byte[] sender, Axiom axiom){ + + public Transaction(ECPrivateKey privateKey, byte[] nonce, byte[] value, byte[] data, byte[] recipient, byte networkId, byte[] sender, Axiom axiom) { this.nonce = nonce; this.value = value; this.data = data; @@ -73,8 +71,8 @@ public Transaction(ECPrivateKey privateKey, byte[] nonce, byte[] value, byte[] d this.hash = getHash(); this.signature = generateSignature(privateKey, axiom); } - - public Transaction(byte[] nonce, byte[] value, byte[] data, byte[] recipient, byte networkId, byte[] signature, byte[] sender){ + + public Transaction(byte[] nonce, byte[] value, byte[] data, byte[] recipient, byte networkId, byte[] signature, byte[] sender) { this.nonce = nonce; this.value = value; this.data = data; @@ -84,12 +82,12 @@ public Transaction(byte[] nonce, byte[] value, byte[] data, byte[] recipient, by this.sender = sender; this.hash = getHash(); } - - public Transaction(byte[] parcel){ + + public Transaction(byte[] parcel) { this(Serializer.getParcelData(parcel), parcel); } - - public Transaction(ParcelData[] parcelData, byte[] parcel){ + + public Transaction(ParcelData[] parcelData, byte[] parcel) { //this.nonce, this.value, this.data, this.recipient, this.networkId, this.sender this.nonce = parcelData[0].getData(); this.value = parcelData[1].getData(); @@ -101,84 +99,88 @@ public Transaction(ParcelData[] parcelData, byte[] parcel){ this.hash = getHash(); this.encoded = parcel; } - + // Methods : - public byte[] getEncoded(){ - if(encoded == null){ + public byte[] getEncoded() { + if (encoded == null) { encoded = Serializer.createParcel(new Object[]{this.nonce, this.value, this.data, this.recipient, this.networkId, this.signature, this.sender}); } return encoded; } - + /* Verify the transactions Signature using an axiom: */ - public boolean verifySignature(Axiom axiom){ + public boolean verifySignature(Axiom axiom) { //use axiom to verify signature. verified = axiom.verifySignature(this); return verified; } - + /* quickly check if the transaction is verified */ - public boolean isVerified(){ + public boolean isVerified() { return verified; } - + /* getter for the transaction hash, if none exists then one will be generated */ - public byte[] getHash(){ + public byte[] getHash() { //Todo This should use an axiom. - if(this.hash == null){ + if (this.hash == null) { this.hash = HashUtil.applySha256( - Serializer.createParcel(new Object[]{ this.nonce, this.value, this.data, this.recipient, this.networkId, this.sender }) + Serializer.createParcel(new Object[]{this.nonce, this.value, this.data, this.recipient, this.networkId, this.sender}) ); } return hash; } - + /* generate signature using an axiom */ - public byte[] generateSignature(ECPrivateKey privateKey, Axiom axiom){ + public byte[] generateSignature(ECPrivateKey privateKey, Axiom axiom) { return axiom.generateSignature(this, privateKey); } - - public byte[] getSender(){ + + public byte[] getSender() { return this.sender; } - - public byte[] getSenderAddress(){ + + public byte[] getSenderAddress() { return KeyUtil.publicKeyToAddress(this.sender); } - - public byte[] getSignature(){ + + public byte[] getSignature() { return this.signature; } - - public byte[] getNonce(){ + + public byte[] getNonce() { return this.nonce; } - - public byte[] getData(){ + + public byte[] getData() { return this.getData(); } - - public byte[] getRecipient(){ + + public byte[] getRecipient() { return this.recipient; } - - public byte networkId(){ + + public byte networkId() { return this.networkId; } - - public byte[] getValue(){ + + public byte[] getValue() { return this.value; } - + + public String getJson() { + return JsonUtil.getJson(this); + } + @Override - public String toString(){ + public String toString() { return "transaction: {\n" + "- sender: " + KeyUtil.publicKeyToAddressString(getSender()) + ", \n" + "- recipient: " + Encoding.bytesToAddress(getRecipient()) + ", \n" + "- value: " + ByteUtil.bytesToBigInteger(getValue()) + ", \n" + "- signature: " + Encoding.bytesToHex(getSignature()) + ", \n" + "- }"; - + } - + } diff --git a/src/main/java/org/dilithium/core/Wallet.java b/src/main/java/org/dilithium/core/Wallet.java index 8b743aa..37c0832 100644 --- a/src/main/java/org/dilithium/core/Wallet.java +++ b/src/main/java/org/dilithium/core/Wallet.java @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2018 Dilithium Team . * * The Dilithium library is free software; you can redistribute it and/or @@ -23,87 +23,92 @@ import java.security.KeyPair; import java.security.interfaces.ECPrivateKey; import java.security.interfaces.ECPublicKey; + import org.dilithium.core.axiom.Axiom; import org.dilithium.db.Context; import org.dilithium.util.ByteUtil; import org.dilithium.util.Encoding; +import org.dilithium.util.JsonUtil; import org.dilithium.util.KeyUtil; /** - * This class + * This class */ public class Wallet { private ECPrivateKey privateKey; private ECPublicKey publicKey; private byte[] address; private Axiom axiom; - - public ECPublicKey getPublicKey(){ + + public ECPublicKey getPublicKey() { return this.publicKey; } - - public byte[] getAddress(){ + + public byte[] getAddress() { return this.address; } - + @Override - public String toString(){ + public String toString() { return "wallet: { \n" + "public-key: " + KeyUtil.publicKeyToString(publicKey) + ", \n" + - "address: " + Encoding.bytesToAddress(address) +" \n" + + "address: " + Encoding.bytesToAddress(address) + " \n" + "}"; } - - public String toString(Context context){ + + public String toString(Context context) { return "wallet: { \n" + "public-key: " + KeyUtil.publicKeyToString(publicKey) + ", \n" + - "address: " + Encoding.bytesToAddress(address) +", \n" + + "address: " + Encoding.bytesToAddress(address) + ", \n" + "balance: " + getBalance(context) + " \n" + "}"; } - - - public Wallet(){ + + + public Wallet() { KeyPair keys = KeyUtil.GenerateKeyPair(); this.privateKey = (ECPrivateKey) keys.getPrivate(); this.publicKey = (ECPublicKey) keys.getPublic(); this.address = KeyUtil.publicKeyToAddress(publicKey); } - - public Wallet(ECPrivateKey privateKey){ + + public Wallet(ECPrivateKey privateKey) { this.privateKey = privateKey; this.publicKey = KeyUtil.privateKeyToPublicKey(privateKey); this.address = KeyUtil.publicKeyToAddress(publicKey); } - + /* returns balance as it is recorded in the given context */ - public BigInteger getBalance(Context context){ + public BigInteger getBalance(Context context) { AccountState account = context.getAccount(address); - if(account != null) { + if (account != null) { return account.getBalance(); - }else{ + } else { return BigInteger.ZERO; } } - + /*generates a transaction, without doing any validity checks */ - public Transaction generateTransaction(BigInteger value, byte[] recipient, byte networkId, Context context, Axiom axiom){ - + public Transaction generateTransaction(BigInteger value, byte[] recipient, byte networkId, Context context, Axiom axiom) { + byte[] nonce = ByteUtil.bigIntegerToBytes(BigInteger.ZERO); byte[] data = ByteUtil.intToBytes(0); byte[] sender = KeyUtil.encodeECPublicKey(publicKey); - + //attempt to get account nonce; AccountState account = context.getAccount(address); - if(account != null){ + if (account != null) { nonce = ByteUtil.bigIntegerToBytes(account.getNonce()); nonce = ByteUtil.increment(nonce); } - + Transaction tx = new Transaction(privateKey, nonce, ByteUtil.bigIntegerToBytes(value), data, recipient, networkId, sender, axiom); //Transaction(ECPrivateKey privateKey, byte[] nonce, byte[] value, byte[] data, byte[] recipient, byte networkId, byte[] sender, Axiom axiom) - + return tx; } - + + public String getJson() { + return JsonUtil.getJson(this); + } } diff --git a/src/main/java/org/dilithium/db/Context.java b/src/main/java/org/dilithium/db/Context.java index 7b206c4..8cc0de9 100644 --- a/src/main/java/org/dilithium/db/Context.java +++ b/src/main/java/org/dilithium/db/Context.java @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2018 Dilithium Team . * * The Dilithium library is free software; you can redistribute it and/or @@ -21,143 +21,149 @@ import java.math.BigInteger; import java.util.HashMap; + import org.dilithium.core.AccountState; import org.dilithium.core.Block; import org.dilithium.core.BlockHeader; import org.dilithium.core.Transaction; import org.dilithium.util.ByteArrayKey; import org.dilithium.util.ByteUtil; +import org.dilithium.util.JsonUtil; /** - * This class + * This class */ public class Context { // Parent to route to : public Context parent; public boolean defaultToMain; - + public HashMap accounts; public HashMap mempool; public HashMap headers; public HashMap blocks; - + //Account state methods. - public AccountState getAccount(byte[] address){ + public AccountState getAccount(byte[] address) { return this.getAccount(new ByteArrayKey(address)); } - - public AccountState getAccount(ByteArrayKey addressKey){ + + public AccountState getAccount(ByteArrayKey addressKey) { AccountState account = null; - + //attempt to find account in current context... account = accounts.get(addressKey); - if(account != null) return account; - + if (account != null) return account; + //attempt to find account in parent context... - if(parent != null){ + if (parent != null) { account = parent.getAccount(addressKey); - if(account != null) return account; + if (account != null) return account; } - + //otherwise default to main database... - if(defaultToMain){ + if (defaultToMain) { byte[] accountParcel = Storage.getInstance().get(StorageMaps.ACCOUNTS, addressKey.toByteArray()); - if(accountParcel != null) { + if (accountParcel != null) { return new AccountState(accountParcel); } } - + //otherwise account doesnt exist in the current context. //create a fresh account state return new AccountState(); } - - public void putAccount(ByteArrayKey addressKey, AccountState account){ + + public void putAccount(ByteArrayKey addressKey, AccountState account) { accounts.put(addressKey, account); } - - public void saveAccountsToDB(){ - for( ByteArrayKey key : accounts.keySet() ){ + + public void saveAccountsToDB() { + for (ByteArrayKey key : accounts.keySet()) { Storage.getInstance().put(StorageMaps.ACCOUNTS, key.toByteArray(), accounts.get(key).getEncoded()); } - + } - + //Block Methods: - public Block getBlock( ByteArrayKey key ){ + public Block getBlock(ByteArrayKey key) { Block block = null; - + //attempt to find account in current context... block = blocks.get(key); - if(block != null) return block; - + if (block != null) return block; + //attempt to find account in parent context... - if(parent != null){ + if (parent != null) { block = parent.getBlock(key); - if(block != null) return block; + if (block != null) return block; } - + //otherwise default to main... - if(defaultToMain){ + if (defaultToMain) { byte[] blockParcel = Storage.getInstance().get(StorageMaps.BLOCKS, key.toByteArray()); - if(blockParcel != null) { + if (blockParcel != null) { //rebuild Block from retrieved blockparcel: return new Block(blockParcel); } } - + //otherwise block doesnt exist in the current context. - return null; + return null; } - - public Block getBlock(long index){ + + public Block getBlock(long index) { byte[] key = ByteUtil.bigIntegerToBytes(BigInteger.valueOf(index)); return this.getBlock(new ByteArrayKey(key)); } - - public void putBlock(Block block){ - byte[] indexBytes = ByteUtil.bigIntegerToBytes( BigInteger.valueOf(block.header.getIndex())); - blocks.put(new ByteArrayKey(indexBytes) , block); + + public void putBlock(Block block) { + byte[] indexBytes = ByteUtil.bigIntegerToBytes(BigInteger.valueOf(block.header.getIndex())); + blocks.put(new ByteArrayKey(indexBytes), block); } - - public void saveBlocksToDB(){ - for( ByteArrayKey key : blocks.keySet() ){ + + public void saveBlocksToDB() { + for (ByteArrayKey key : blocks.keySet()) { Storage.getInstance().put(StorageMaps.BLOCKS, key.toByteArray(), blocks.get(key).getEncoded()); } } - - public long calculateChainSize(){ + + public long calculateChainSize() { long largestIndex = 0L; long current; - for(ByteArrayKey indexKey : blocks.keySet()){ + for (ByteArrayKey indexKey : blocks.keySet()) { current = ByteUtil.bytesToBigInteger(indexKey.toByteArray()).longValue(); largestIndex = (current > largestIndex) ? current : largestIndex; } return largestIndex + 1; } - + //Constructors - public Context(){ - this(null,false); + public Context() { + this(null, false); } - - public Context(Context parent, boolean defaultToMain){ + + public Context(Context parent, boolean defaultToMain) { this.parent = parent; this.defaultToMain = defaultToMain; - this.accounts = new HashMap() ; - this.mempool = new HashMap() ; - this.headers = new HashMap() ; - this.blocks = new HashMap(); + this.accounts = new HashMap(); + this.mempool = new HashMap(); + this.headers = new HashMap(); + this.blocks = new HashMap(); + } + + public String getJson() { + return JsonUtil.getJson(this); } - + // - @Override - public String toString(){ - return "context-content: { \n" + + public String toString() { + return "context-content: { \n" + "accounts: " + accounts.size() + ", \n" + "blocks: " + blocks.size() + ", \n" + - "mempool: " + mempool.size() + " },\n" + + "mempool: " + mempool.size() + " },\n" + "}"; } - + } diff --git a/src/main/java/org/dilithium/util/JsonUtil.java b/src/main/java/org/dilithium/util/JsonUtil.java new file mode 100644 index 0000000..9735bdf --- /dev/null +++ b/src/main/java/org/dilithium/util/JsonUtil.java @@ -0,0 +1,12 @@ +package org.dilithium.util; + +import com.google.gson.Gson; + +public class JsonUtil { + private static final Gson GSON = new Gson(); + + public static String getJson(Object object){ + return GSON.toJson(object); + } + +} From a2ce0332f2e1c2b8aa5ebe6b0ef06fcb25fa7b45 Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 14 May 2018 23:07:33 +0200 Subject: [PATCH 2/3] Renamed Context to StorageContext --- src/main/java/org/dilithium/Start.java | 6 ++-- .../dilithium/cli/commands/NodeCommand.java | 6 ++-- src/main/java/org/dilithium/core/Block.java | 4 +-- .../org/dilithium/core/BlockProcessor.java | 6 ++-- src/main/java/org/dilithium/core/Miner.java | 5 ++- src/main/java/org/dilithium/core/Node.java | 36 +++++++++---------- src/main/java/org/dilithium/core/Wallet.java | 8 ++--- .../java/org/dilithium/core/axiom/Axiom.java | 6 ++-- .../org/dilithium/core/axiom/AxiomD0.java | 6 ++-- .../db/{Context.java => StorageContext.java} | 8 ++--- 10 files changed, 45 insertions(+), 46 deletions(-) rename src/main/java/org/dilithium/db/{Context.java => StorageContext.java} (96%) diff --git a/src/main/java/org/dilithium/Start.java b/src/main/java/org/dilithium/Start.java index 992e24c..9387bb6 100644 --- a/src/main/java/org/dilithium/Start.java +++ b/src/main/java/org/dilithium/Start.java @@ -27,7 +27,7 @@ import org.dilithium.config.NodeSettings; import org.dilithium.core.Node; import org.dilithium.core.Wallet; -import org.dilithium.db.Context; +import org.dilithium.db.StorageContext; import org.dilithium.util.KeyUtil; import org.dilithium.util.Log; @@ -38,7 +38,7 @@ public class Start { public static NodeSettings config; public static Wallet localWallet; - public static Context localContext; + public static StorageContext localContext; public static Node localNode; /* This method is run when the program first starts */ @@ -56,7 +56,7 @@ public static void main(String[] args) { /* Get local database and storage context * will contain the local state of blocks and accounts*/ - localContext = new Context(); + localContext = new StorageContext(); Log.log(Level.INFO, "\nLocalContext: " + localContext.toString()); /* Setup temp local wallet */ diff --git a/src/main/java/org/dilithium/cli/commands/NodeCommand.java b/src/main/java/org/dilithium/cli/commands/NodeCommand.java index 820ffff..dbd62e0 100644 --- a/src/main/java/org/dilithium/cli/commands/NodeCommand.java +++ b/src/main/java/org/dilithium/cli/commands/NodeCommand.java @@ -24,7 +24,7 @@ import org.dilithium.Start; import org.dilithium.cli.Commander; import org.dilithium.core.Block; -import org.dilithium.db.Context; +import org.dilithium.db.StorageContext; import org.dilithium.serialization.Json; /** @@ -76,9 +76,9 @@ public void run(String[] args) { Commander.CommanderPrint("Fetching block..."); Commander.CommanderPrint("Searching for block with index: " + indexString); - Context context = Start.localNode.getContext(); + StorageContext storageContext = Start.localNode.getStorageContext(); long index = Long.parseLong(indexString); - Block block = context.getBlock(index); + Block block = storageContext.getBlock(index); if(block == null) { Commander.CommanderPrint("ERROR ! block not found."); diff --git a/src/main/java/org/dilithium/core/Block.java b/src/main/java/org/dilithium/core/Block.java index 5e7525d..c3d4abb 100644 --- a/src/main/java/org/dilithium/core/Block.java +++ b/src/main/java/org/dilithium/core/Block.java @@ -24,7 +24,7 @@ import org.dilithium.Start; import org.dilithium.core.axiom.Axiom; import org.dilithium.core.axiom.AxiomManager; -import org.dilithium.db.Context; +import org.dilithium.db.StorageContext; import org.dilithium.serialization.ParcelData; import org.dilithium.serialization.Serializer; import org.dilithium.util.ByteUtil; @@ -42,7 +42,7 @@ public class Block { private boolean parsed = false; private byte[] axiomID; private Axiom axiom; - private Context context; + private StorageContext context; public Block(BlockHeader header, Axiom axiom, List transactions){ this.header = header; diff --git a/src/main/java/org/dilithium/core/BlockProcessor.java b/src/main/java/org/dilithium/core/BlockProcessor.java index 52a3813..07ec021 100644 --- a/src/main/java/org/dilithium/core/BlockProcessor.java +++ b/src/main/java/org/dilithium/core/BlockProcessor.java @@ -8,7 +8,7 @@ import java.math.BigInteger; import org.dilithium.core.axiom.Axiom; -import org.dilithium.db.Context; +import org.dilithium.db.StorageContext; import org.dilithium.util.Log; import java.util.logging.Level; import org.dilithium.util.ByteArrayKey; @@ -21,11 +21,11 @@ */ public class BlockProcessor { - public boolean addBlock(byte[] blockParcel, Context context){ + public boolean addBlock(byte[] blockParcel, StorageContext context){ return addBlock(new Block(blockParcel), context); } - public boolean addBlock(Block block, Context context){ + public boolean addBlock(Block block, StorageContext context){ BlockHeader header = block.header; //get the axiom from the block; diff --git a/src/main/java/org/dilithium/core/Miner.java b/src/main/java/org/dilithium/core/Miner.java index 6317ef0..6de6822 100644 --- a/src/main/java/org/dilithium/core/Miner.java +++ b/src/main/java/org/dilithium/core/Miner.java @@ -23,10 +23,9 @@ import java.util.logging.Level; import org.bouncycastle.util.encoders.Hex; -import org.dilithium.cli.Commander; import org.dilithium.core.axiom.Axiom; import org.dilithium.core.axiom.AxiomManager; -import org.dilithium.db.Context; +import org.dilithium.db.StorageContext; import org.dilithium.util.ByteUtil; import org.dilithium.util.Log; @@ -35,7 +34,7 @@ */ public class Miner { - public Context context; + public StorageContext storageContext; private Block block; diff --git a/src/main/java/org/dilithium/core/Node.java b/src/main/java/org/dilithium/core/Node.java index ee3c29b..7a65099 100644 --- a/src/main/java/org/dilithium/core/Node.java +++ b/src/main/java/org/dilithium/core/Node.java @@ -28,7 +28,7 @@ import org.dilithium.config.NodeSettings; import org.dilithium.core.axiom.Axiom; import org.dilithium.core.genesis.GenesisBlock; -import org.dilithium.db.Context; +import org.dilithium.db.StorageContext; import org.dilithium.networking.Peer2Peer; import org.dilithium.util.Encoding; @@ -36,10 +36,10 @@ * This Class handles the block-chain as a full-node. */ public class Node implements Runnable{ - /* The storage and db context used by this node */ - private Context context; + /* The storage and db storageContext used by this node */ + private StorageContext storageContext; - /* The first block in the blockchain, via context */ + /* The first block in the blockchain, via storageContext */ private Block genesisBlock; /* The wallet that will recieve rewards for each block mined (If the current axiom supports that */ @@ -51,7 +51,7 @@ public class Node implements Runnable{ /* The current axiom in use by the latest block in the blockchain */ private Axiom axiom; - /* The header from the latest block in the blockchain, via context. */ + /* The header from the latest block in the blockchain, via storageContext. */ private BlockHeader tallestHeader; /* The block that is being mined */ @@ -65,32 +65,32 @@ public class Node implements Runnable{ private Peer2Peer p2p; private int serverPort = 8888; - /* Checks block and updates the state and adds it to the db context */ + /* Checks block and updates the state and adds it to the db storageContext */ private BlockProcessor blockProcessor; /* Transactions to be added to block */ private Queue transactionPool; //Contructor - public Node(Context context, Block genesisBlock, Miner miner, Axiom axiom){ - this.context = context; + public Node(StorageContext storageContext, Block genesisBlock, Miner miner, Axiom axiom){ + this.storageContext = storageContext; this.genesisBlock = genesisBlock; this.miner = miner; this.minerWallet = Start.localWallet; this.axiom = axiom; this.tallestHeader = genesisBlock.header; this.blockProcessor = new BlockProcessor(); - blockProcessor.addBlock(genesisBlock, context); + blockProcessor.addBlock(genesisBlock, storageContext); transactionPool = new PriorityQueue(); } public Node(){ - this(Start.localContext,GenesisBlock.getInstance().getBlock(), null, NodeSettings.getDefault().getAxiom() ); + this(Start.localContext, GenesisBlock.getInstance().getBlock(), null, NodeSettings.getDefault().getAxiom() ); } //getters public long getLength(){ - return this.context.calculateChainSize(); + return this.storageContext.calculateChainSize(); } public int getPort(){ @@ -105,8 +105,8 @@ public boolean isMining(){ return this.shouldMine; } - public Context getContext(){ - return this.context; + public StorageContext getStorageContext(){ + return this.storageContext; } //Methods @@ -180,12 +180,12 @@ private void mine(){ } //block has been mined - Commander.CommanderPrint("Newly mined block is valid:" + axiom.isBlockValid(minedBlock, context)); - Commander.CommanderPrint("Adding new block to context..."); + Commander.CommanderPrint("Newly mined block is valid:" + axiom.isBlockValid(minedBlock, storageContext)); + Commander.CommanderPrint("Adding new block to storageContext..."); //Add mined block to db: - //context.putBlock(minedBlock); - blockProcessor.addBlock(minedBlock, context); + //storageContext.putBlock(minedBlock); + blockProcessor.addBlock(minedBlock, storageContext); //Update tallest header: tallestHeader = minedBlock.header; @@ -202,7 +202,7 @@ public void setPort(int number){ } public AccountState getAccount(byte[] address){ - return context.getAccount(address); + return storageContext.getAccount(address); } //Overrides diff --git a/src/main/java/org/dilithium/core/Wallet.java b/src/main/java/org/dilithium/core/Wallet.java index 37c0832..b713c95 100644 --- a/src/main/java/org/dilithium/core/Wallet.java +++ b/src/main/java/org/dilithium/core/Wallet.java @@ -25,7 +25,7 @@ import java.security.interfaces.ECPublicKey; import org.dilithium.core.axiom.Axiom; -import org.dilithium.db.Context; +import org.dilithium.db.StorageContext; import org.dilithium.util.ByteUtil; import org.dilithium.util.Encoding; import org.dilithium.util.JsonUtil; @@ -56,7 +56,7 @@ public String toString() { "}"; } - public String toString(Context context) { + public String toString(StorageContext context) { return "wallet: { \n" + "public-key: " + KeyUtil.publicKeyToString(publicKey) + ", \n" + "address: " + Encoding.bytesToAddress(address) + ", \n" + @@ -79,7 +79,7 @@ public Wallet(ECPrivateKey privateKey) { } /* returns balance as it is recorded in the given context */ - public BigInteger getBalance(Context context) { + public BigInteger getBalance(StorageContext context) { AccountState account = context.getAccount(address); if (account != null) { return account.getBalance(); @@ -89,7 +89,7 @@ public BigInteger getBalance(Context context) { } /*generates a transaction, without doing any validity checks */ - public Transaction generateTransaction(BigInteger value, byte[] recipient, byte networkId, Context context, Axiom axiom) { + public Transaction generateTransaction(BigInteger value, byte[] recipient, byte networkId, StorageContext context, Axiom axiom) { byte[] nonce = ByteUtil.bigIntegerToBytes(BigInteger.ZERO); byte[] data = ByteUtil.intToBytes(0); diff --git a/src/main/java/org/dilithium/core/axiom/Axiom.java b/src/main/java/org/dilithium/core/axiom/Axiom.java index c856a54..943671b 100644 --- a/src/main/java/org/dilithium/core/axiom/Axiom.java +++ b/src/main/java/org/dilithium/core/axiom/Axiom.java @@ -23,7 +23,7 @@ import org.dilithium.core.Block; import org.dilithium.core.BlockHeader; import org.dilithium.core.Transaction; -import org.dilithium.db.Context; +import org.dilithium.db.StorageContext; /* * The axiom is a set of rules and methods, for generating and validating blocks and transactions. @@ -51,10 +51,10 @@ public interface Axiom { public Transaction updateTransction(Transaction tx); - public boolean verifyTransaction(Transaction tx, Context context); + public boolean verifyTransaction(Transaction tx, StorageContext context); public boolean verifySignature(Transaction tx); public byte[] generateSignature(Transaction tx, PrivateKey privateKey); public String toString(); public boolean isBlockSolutionValid(BlockHeader header); - public boolean isBlockValid(Block block, Context context); + public boolean isBlockValid(Block block, StorageContext context); } diff --git a/src/main/java/org/dilithium/core/axiom/AxiomD0.java b/src/main/java/org/dilithium/core/axiom/AxiomD0.java index 4695782..003be88 100644 --- a/src/main/java/org/dilithium/core/axiom/AxiomD0.java +++ b/src/main/java/org/dilithium/core/axiom/AxiomD0.java @@ -33,7 +33,7 @@ import org.dilithium.core.BlockHeader; import org.dilithium.core.Transaction; import org.dilithium.core.genesis.GenesisBlock; -import org.dilithium.db.Context; +import org.dilithium.db.StorageContext; import org.dilithium.util.ByteUtil; import org.dilithium.util.HashUtil; import org.dilithium.util.KeyUtil; @@ -92,7 +92,7 @@ public BigInteger getBlockReward(BlockHeader headers){ } @Override - public boolean verifyTransaction(Transaction tx, Context context) { + public boolean verifyTransaction(Transaction tx, StorageContext context) { //check if transaction signature is valid; if(!tx.isVerified()){ if(!tx.verifySignature(this)) return false; @@ -165,7 +165,7 @@ public boolean isBlockSolutionValid(BlockHeader header) { } @Override - public boolean isBlockValid(Block block, Context context){ + public boolean isBlockValid(Block block, StorageContext context){ boolean isGenesis; diff --git a/src/main/java/org/dilithium/db/Context.java b/src/main/java/org/dilithium/db/StorageContext.java similarity index 96% rename from src/main/java/org/dilithium/db/Context.java rename to src/main/java/org/dilithium/db/StorageContext.java index 8cc0de9..638baa4 100644 --- a/src/main/java/org/dilithium/db/Context.java +++ b/src/main/java/org/dilithium/db/StorageContext.java @@ -33,9 +33,9 @@ /** * This class */ -public class Context { +public class StorageContext { // Parent to route to : - public Context parent; + public StorageContext parent; public boolean defaultToMain; public HashMap accounts; @@ -139,11 +139,11 @@ public long calculateChainSize() { } //Constructors - public Context() { + public StorageContext() { this(null, false); } - public Context(Context parent, boolean defaultToMain) { + public StorageContext(StorageContext parent, boolean defaultToMain) { this.parent = parent; this.defaultToMain = defaultToMain; this.accounts = new HashMap(); From 04da424fd33fda5663fe860b59442c9274a41c1a Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 14 May 2018 23:27:52 +0200 Subject: [PATCH 3/3] Byte[] increment --- .../java/org/dilithium/util/ByteUtil.java | 148 ++++++++---------- 1 file changed, 65 insertions(+), 83 deletions(-) diff --git a/src/main/java/org/dilithium/util/ByteUtil.java b/src/main/java/org/dilithium/util/ByteUtil.java index eb50a83..5310f27 100644 --- a/src/main/java/org/dilithium/util/ByteUtil.java +++ b/src/main/java/org/dilithium/util/ByteUtil.java @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2018 Dilithium Team . * * The Dilithium library is free software; you can redistribute it and/or @@ -30,6 +30,7 @@ import java.security.spec.ECPoint; import java.util.ArrayList; import java.util.List; + import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Primitive; @@ -39,12 +40,12 @@ * wish to change how this is done, so its useful to only have to change it in one place. */ public class ByteUtil { - + public static int getUnsignedByte(byte input) { return input & 0xFF; - } - - public static byte[] charArrayToBytes(char[] input){ + } + + public static byte[] charArrayToBytes(char[] input) { CharBuffer charBuffer = CharBuffer.wrap(input); ByteBuffer byteBuffer = Charset.forName("UTF-8").encode(charBuffer); @@ -55,19 +56,19 @@ public static byte[] charArrayToBytes(char[] input){ return bytes; } - + /* short hand method that converts string to bytes, ensures charset is UTF-8 */ - public static byte[] stringToBytes(String input){ + public static byte[] stringToBytes(String input) { return input.getBytes(Charset.forName("UTF-8")); } - + /* converts long to bytes, useful for hashing or serialization */ - public static byte[] longToBytes(long input){ + public static byte[] longToBytes(long input) { ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES); buffer.putLong(input); return buffer.array(); } - + /* converts a BigInteger to bytes, useful for hashing or serialization */ public static byte[] bigIntegerToBytes(BigInteger input) { byte[] buffer = input.toByteArray(); @@ -78,28 +79,28 @@ public static byte[] bigIntegerToBytes(BigInteger input) { }*/ return buffer; } - + /* int to bytes */ - public static byte[] intToBytes(int input){ + public static byte[] intToBytes(int input) { return ByteBuffer.allocate(4).putInt(input).array(); } - + /* short to bytes */ - public static byte[] shortToBytes(short input){ + public static byte[] shortToBytes(short input) { return ByteBuffer.allocate(2).putShort(input).array(); } - - public static short getShortFromBytes(byte[] input){ + + public static short getShortFromBytes(byte[] input) { return ByteBuffer.wrap(input).getShort(); } - + /* converts bytes back into an Integer */ - public static int bytesToInt(byte[] input){ + public static int bytesToInt(byte[] input) { return ByteBuffer.wrap(input).getInt(); } - + /* converts bytes back into a string, attempts to use UTF-8 first */ - public static String bytesToString(byte[] input){ + public static String bytesToString(byte[] input) { try { //try to create new bytes uing utf-8 return new String(input, "UTF-8"); @@ -108,116 +109,97 @@ public static String bytesToString(byte[] input){ return new String(input); } } - + /* converts bytes back into Big Integer */ - public static BigInteger bytesToBigInteger(byte[] input){ + public static BigInteger bytesToBigInteger(byte[] input) { return new BigInteger(input); } - + /* converts bytes back into a string array */ - public static String[] bytesToStringArray(byte[] input){ + public static String[] bytesToStringArray(byte[] input) { //TODO: populate method: return null; } - + /* concats two byte arrays [] into one in the order "ab". */ public static byte[] concatenateBytes(byte[] a, byte[] b) { - byte[] result = new byte[a.length + b.length]; - System.arraycopy(a, 0, result, 0, a.length); - System.arraycopy(b, 0, result, a.length, b.length); + byte[] result = new byte[a.length + b.length]; + System.arraycopy(a, 0, result, 0, a.length); + System.arraycopy(b, 0, result, a.length, b.length); return result; } - + /* Converts ecPoint to a bytearray, java.security.spec.ECPoint not to be confused with bouncey castle ecpoint.*/ - public static byte[] ecPointToBytes( ECPoint input ){ + public static byte[] ecPointToBytes(ECPoint input) { BigInteger qx = input.getAffineX(); BigInteger qy = input.getAffineY(); byte[] qyBytes = bigIntegerToBytes(qy); byte[] qxBytes = bigIntegerToBytes(qx); byte[] xlengthBytes = new byte[1]; //info bit - - + + //fix length issues xlengthBytes[0] = (byte) qxBytes.length; - byte[] buffer = concatenateBytes(xlengthBytes,bigIntegerToBytes(qx)); - buffer = concatenateBytes(buffer,bigIntegerToBytes(qy)); - return buffer; + byte[] buffer = concatenateBytes(xlengthBytes, bigIntegerToBytes(qx)); + buffer = concatenateBytes(buffer, bigIntegerToBytes(qy)); + return buffer; } - + /* Converts byte array bck into an ecpoint */ - public static ECPoint bytesToECPoint(byte[] input ){ + public static ECPoint bytesToECPoint(byte[] input) { int midpoint = (int) input[0]; - BigInteger qx = bytesToBigInteger(Arrays.copyOfRange(input,1, midpoint+1)); - BigInteger qy = bytesToBigInteger(Arrays.copyOfRange(input,midpoint+1,input.length)); - return new ECPoint(qx,qy); + BigInteger qx = bytesToBigInteger(Arrays.copyOfRange(input, 1, midpoint + 1)); + BigInteger qy = bytesToBigInteger(Arrays.copyOfRange(input, midpoint + 1, input.length)); + return new ECPoint(qx, qy); } - + //DER - public static ASN1Primitive toAsn1Object(byte[] data) throws IOException - { + public static ASN1Primitive toAsn1Object(byte[] data) throws IOException { ByteArrayInputStream inStream = new ByteArrayInputStream(data); ASN1InputStream asnInputStream = new ASN1InputStream(inStream); return asnInputStream.readObject(); } - + //Increment public static byte[] increment(byte[] input) { - /* boolean carryOver = true; - int len = (input.length - 1); - for (int i = len; i >= 0; i--) { - if (carryOver) { - if (input[i] == 0) { - input[i] = 1; - carryOver = false; - } - else { - input[i] = 0; - carryOver = true; - } + for (int i = input.length - 1; i >= 0; --i) { + if (++input[i] != 0) { + return input; } - }*/ - // i = bytesToInt(input); - //i++; - - //return intToBytes(i); - - BigInteger i = bytesToBigInteger(input); - i = i.add(BigInteger.ONE); - - return bigIntegerToBytes(i); - - } - + } + throw new IllegalStateException("Counter overflow"); + } + //Populate with - public static byte[] populate(byte[] array,byte input){ - for(int i=0;i < array.length; i++){ + public static byte[] populate(byte[] array, byte input) { + for (int i = 0; i < array.length; i++) { array[i] = input; } return array; } - + //get byte time - public static byte[] getNowTimeStamp(){ + public static byte[] getNowTimeStamp() { int dateInSec = (int) (System.currentTimeMillis() / 1000); return ByteBuffer.allocate(4).putInt(dateInSec).array(); - + } - - public static List parcelDataToListBytes( byte[] parcelData ){ - int cursor = 0; + + public static List parcelDataToListBytes(byte[] parcelData) { + int cursor = 0; int length = 0; List listBytes = new ArrayList(); - while(cursor < parcelData.length-1){ - length = (int) ByteUtil.getShortFromBytes(Arrays.copyOfRange(parcelData,cursor,cursor+2)); - cursor+=2; //move cursor along to start of data bytes - listBytes.add(Arrays.copyOfRange(parcelData,cursor,cursor+length)); + while (cursor < parcelData.length - 1) { + length = (int) ByteUtil.getShortFromBytes(Arrays.copyOfRange(parcelData, cursor, cursor + 2)); + cursor += 2; //move cursor along to start of data bytes + listBytes.add(Arrays.copyOfRange(parcelData, cursor, cursor + length)); cursor += length; //move cursor to end of content } return listBytes; } - - + + }