changeset 151:acf127ec8d8c

マージ fizzbuzz
author musou_aka
date Tue, 08 Jan 2019 19:03:33 +0900
parents 37b28ffbab2f (diff) a5cd12f6a942 (current diff)
children 57f4ef5e3d08
files
diffstat 24 files changed, 344 insertions(+), 141 deletions(-) [+]
line wrap: on
line diff
--- a/src/main/java/christie/blockchain/Block.java	Mon Jan 07 17:20:53 2019 +0900
+++ b/src/main/java/christie/blockchain/Block.java	Tue Jan 08 19:03:33 2019 +0900
@@ -53,8 +53,8 @@
         return this.header.getNonce();
     }
 
-    public byte[] getPresentHashWithoutNonce(){
-        return this.header.getPresentHashWithoutNonce();
+    public byte[] getByteArrayWithoutNonce(){
+        return this.header.getByteArrayWithoutNonce();
     }
 
     public long getNumber() {
--- a/src/main/java/christie/blockchain/BlockChain.java	Mon Jan 07 17:20:53 2019 +0900
+++ b/src/main/java/christie/blockchain/BlockChain.java	Tue Jan 08 19:03:33 2019 +0900
@@ -1,6 +1,7 @@
 package christie.blockchain;
 
 import java.nio.charset.Charset;
+import java.security.Security;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -9,24 +10,39 @@
 
     public ArrayList<Block> blockList = new ArrayList<Block>();
 
+    int difficulty = 1;
+
+    private Block bestBlock;
 
 
     public static void main(String[] args) {
-        int difficulty = 1;
+
+        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
+
+        ECKey ecKeyA = new ECKey();
+        ECKey ecKeyB = new ECKey();
+
+        Transaction transaction = new Transaction(ecKeyA.getPublicKey(), ecKeyB.getPublicKey(), "hello");
+        transaction.generateSignature(ecKeyA.getPrivateKey());
+        System.out.println(transaction.verifiySignature());
+    }
+
+    public void testBlockMining(){
         BlockChain blockChain = new BlockChain();
+        blockChain.difficulty = 1;
         Miner miner = new Miner();
         long startTime = System.currentTimeMillis();
 
-        Block genesisBlock = blockChain.createGenesisBlock("Hi im the first block");
-        miner.mineBlock(genesisBlock, difficulty);
+        Block genesisBlock = blockChain.createNewBlock("Hi im the first block");
+        miner.mineBlock(genesisBlock, blockChain.difficulty);
         System.out.println("Hash for block 1 : " + genesisBlock.getData() + " Nonce : " + genesisBlock.getNonce());
 
         Block secondBlock = blockChain.createNewBlock(genesisBlock, "Yo im the second block");
-        miner.mineBlock(secondBlock, difficulty);
+        miner.mineBlock(secondBlock, blockChain.difficulty);
         System.out.println("Hash for block 2 : " + secondBlock.getData() + " Nonce : " + secondBlock.getNonce());
 
         Block thirdBlock = blockChain.createNewBlock(secondBlock, "Hey im the third block");
-        miner.mineBlock(thirdBlock, difficulty);
+        miner.mineBlock(thirdBlock, blockChain.difficulty);
         System.out.println("Hash for block 3 : " + thirdBlock.getData() + " Nonce : " + thirdBlock.getNonce());
 
 
@@ -34,12 +50,13 @@
         blockChain.blockList.add(secondBlock);
         blockChain.blockList.add(thirdBlock);
 
-        System.out.println("\nBlockchain is Valid: " + blockChain.isChainValid(difficulty));
+        System.out.println("\nBlockchain is Valid: " + blockChain.isChainValid(blockChain.difficulty));
 
         long endTime = System.currentTimeMillis() - startTime;
 
         System.out.println("end Time: " + endTime);
 
+
     }
 
     public Boolean isChainValid(int difficulty) {
@@ -67,6 +84,10 @@
         return true;
     }
 
+    public synchronized Block createNewBlock(String data) {
+        return createGenesisBlock(data);
+    }
+
     public synchronized Block createNewBlock(Block parent, String data){
         long time = System.currentTimeMillis() / 1000;
         // もし, 時差があって, timeが親のタイムスタンプより低いなら, 親のタイムスタンプ + 1 を代入する
@@ -93,5 +114,8 @@
         return block;
     }
 
+    public synchronized Block getBestBlock() {
+        return bestBlock;
+    }
 
 }
--- a/src/main/java/christie/blockchain/BlockHeader.java	Mon Jan 07 17:20:53 2019 +0900
+++ b/src/main/java/christie/blockchain/BlockHeader.java	Tue Jan 08 19:03:33 2019 +0900
@@ -30,7 +30,7 @@
         this.timestamp = timestamp;
     }
 
-    public byte[] getHash(boolean withNonce){
+    public byte[] getParamByteArray(boolean withNonce){
 
         ByteArrayOutputStream output = new ByteArrayOutputStream();
 
@@ -57,15 +57,18 @@
     }
 
     public byte[] getParentHash() {
+
         return parentHash;
     }
 
     public byte[] getPresentHash() {
-        return hashUtil.sha256(getHash(true));
+
+        return hashUtil.sha256(getParamByteArray(true));
     }
 
-    public byte[] getPresentHashWithoutNonce(){
-        return getHash(false);
+    public byte[] getByteArrayWithoutNonce(){
+
+        return getParamByteArray(false);
     }
 
     public void setTimestamp(long timestamp) {
--- a/src/main/java/christie/blockchain/ECKey.java	Mon Jan 07 17:20:53 2019 +0900
+++ b/src/main/java/christie/blockchain/ECKey.java	Tue Jan 08 19:03:33 2019 +0900
@@ -11,6 +11,7 @@
 import java.security.*;
 import java.security.interfaces.ECPublicKey;
 import java.security.spec.ECGenParameterSpec;
+import java.util.Arrays;
 
 
 public class ECKey {
@@ -25,6 +26,9 @@
     private final PublicKey publicKey;
     private final Provider provider;
 
+    HashUtil hashUtil = new HashUtil();
+
+
     static {
         X9ECParameters params = SECNamedCurves.getByName("secp256k1");
         CURVE = new ECDomainParameters(params.getCurve(), params.getG(), params.getN(), params.getH());
@@ -71,14 +75,14 @@
         return CURVE.getCurve().createPoint(xCoord, yCoord);
     }
 
-    public byte[] applyECDSASig(byte[] input) {
+    public byte[] applyECDSASig(PrivateKey privateKey, byte[] input) {
         Signature dsa;
         byte[] output;
 
         if (privateKey == null)
             throw new RuntimeException();
         try {
-            dsa = Signature.getInstance("ECDSA", "BC");
+            dsa = Signature.getInstance("ECDSA","BC");
             dsa.initSign(privateKey);
             dsa.update(input);
             output = dsa.sign();
@@ -88,7 +92,7 @@
         return output;
     }
 
-    public static boolean verifyECDSASig(byte[] data, byte[] signature, PublicKey publicKey) {
+    public boolean verifyECDSASig(PublicKey publicKey, byte[] data, byte[] signature) {
         try {
             Signature ecdsaVerify = Signature.getInstance("ECDSA", "BC");
             ecdsaVerify.initVerify(publicKey);
@@ -99,4 +103,11 @@
         }
     }
 
+    public PrivateKey getPrivateKey() {
+        return privateKey;
+    }
+
+    public PublicKey getPublicKey() {
+        return publicKey;
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/christie/blockchain/FileData.java	Tue Jan 08 19:03:33 2019 +0900
@@ -0,0 +1,26 @@
+package christie.blockchain;
+
+
+import org.msgpack.annotation.Message;
+
+import java.io.File;
+
+@Message
+public class FileData {
+
+    String filepath = "";
+    File file;
+
+    public FileData(){}
+
+    public File read(){
+        return this.file;
+
+    }
+
+    public void write(){
+
+    }
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/christie/blockchain/FileManager.java	Tue Jan 08 19:03:33 2019 +0900
@@ -0,0 +1,16 @@
+package christie.blockchain;
+
+import java.io.File;
+
+public class FileManager {
+
+
+    public void save(){
+
+    }
+
+    public void write(){
+
+    }
+
+}
--- a/src/main/java/christie/blockchain/HashUtil.java	Mon Jan 07 17:20:53 2019 +0900
+++ b/src/main/java/christie/blockchain/HashUtil.java	Tue Jan 08 19:03:33 2019 +0900
@@ -2,6 +2,8 @@
 
 import org.bouncycastle.crypto.digests.*;
 
+import static java.util.Arrays.copyOfRange;
+
 
 public class HashUtil {
     public byte[] sha256(byte[] input) {
@@ -42,6 +44,11 @@
         return resBuf;
     }
 
+    public byte[] sha3omit12(byte[] input) {
+        byte[] hash = sha3(input);
+        return copyOfRange(hash, 12, hash.length);
+    }
+
 
 
 }
--- a/src/main/java/christie/blockchain/Miner.java	Mon Jan 07 17:20:53 2019 +0900
+++ b/src/main/java/christie/blockchain/Miner.java	Tue Jan 08 19:03:33 2019 +0900
@@ -19,7 +19,7 @@
 
         //byte[] target = new String(new char[difficulty]).replace('\0', '0').getBytes();
         String target = new String(new char[difficulty]).replace('\0', '0');
-        byte[] hash = newBlock.getPresentHashWithoutNonce();
+        byte[] hash = newBlock.getByteArrayWithoutNonce();
 
         String hashStr = new String(hashUtil.sha256(hash), Charset.forName("utf-8"));
 
--- a/src/main/java/christie/blockchain/Transaction.java	Mon Jan 07 17:20:53 2019 +0900
+++ b/src/main/java/christie/blockchain/Transaction.java	Tue Jan 08 19:03:33 2019 +0900
@@ -3,6 +3,8 @@
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.math.BigInteger;
+import java.security.PrivateKey;
+import java.security.PublicKey;
 
 // インターフェイスにしたほうがいいかもしれない. 後からdataの内容変える可能性がある.
 public class Transaction {
@@ -10,21 +12,26 @@
 
     private long nonce;
 
-    private byte[] sendAddress;
+    private PublicKey sendAddress;
 
-    private byte[] receiveAddress;
+    private PublicKey receiveAddress;
 
-    private byte[] data;
+    private String data;
 
     private long timestamp;
 
     private byte[] signature;
 
+    HashUtil hashUtil = new HashUtil();
+
+    ECKey ecKey = new ECKey();
+
+
     //public ArrayList<TransactionInput> inputs = new ArrayList<TransactionInput>();
     //public ArrayList<TransactionOutput> outputs = new ArrayList<TransactionOutput>();
 
 
-    public Transaction(byte[] sendAddress, byte[] receiveAddress, byte[] data){
+    public Transaction(PublicKey sendAddress, PublicKey receiveAddress, String data){
         this.sendAddress = sendAddress;
         this.receiveAddress = receiveAddress;
         this.data = data;
@@ -38,25 +45,59 @@
         this.inputs = inputs;
     }
 */
-    public byte[] calcHash(){
-        HashUtil hashUtil = new HashUtil();
 
-        byte[] timestampByte = BigInteger.valueOf(this.timestamp).toByteArray();
-
-        byte[] nonceByte = BigInteger.valueOf(this.nonce).toByteArray();
+    public byte[] getParamByteArray(){
 
         ByteArrayOutputStream output = new ByteArrayOutputStream();
 
+        byte[] timestampByte = BigInteger.valueOf(this.timestamp).toByteArray();
+        byte[] nonceByte = BigInteger.valueOf(this.nonce).toByteArray();
         try {
-            output.write(hash);
+            output.write(sendAddress.getEncoded());
+            output.write(receiveAddress.getEncoded());
+            output.write(nonceByte);
             output.write(timestampByte);
-            output.write(nonceByte);
+            output.write(signature);
         } catch (IOException e) {
             e.printStackTrace();
         }
 
-        return hashUtil.sha256(output.toByteArray());
+
+        return output.toByteArray();
 
     }
 
+    public byte[] gethash() {
+
+        return hashUtil.sha256(getParamByteArray());
+    }
+
+    public void generateSignature(PrivateKey privateKey) {
+        ByteArrayOutputStream _data = new ByteArrayOutputStream();
+        try {
+            _data.write(sendAddress.getEncoded());
+            _data.write(receiveAddress.getEncoded());
+            _data.write(data.getBytes());
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        signature = ecKey.applyECDSASig(privateKey, _data.toByteArray());
+    }
+    //Verifies the data we signed hasnt been tampered with
+    public boolean verifiySignature() {
+        ByteArrayOutputStream _data = new ByteArrayOutputStream();
+        try {
+            _data.write(sendAddress.getEncoded());
+            _data.write(receiveAddress.getEncoded());
+            _data.write(data.getBytes());
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        return ecKey.verifyECDSASig(sendAddress, _data.toByteArray(), signature);
+    }
+
+
+
+
 }
--- a/src/main/java/christie/codegear/CodeGearManager.java	Mon Jan 07 17:20:53 2019 +0900
+++ b/src/main/java/christie/codegear/CodeGearManager.java	Tue Jan 08 19:03:33 2019 +0900
@@ -71,4 +71,12 @@
     public void setAccept(String key, IncomingTcpConnection in) {
         acceptHash.put(key, in);
     }
+
+    // broadcast data
+    public void putAllDGM(String key, Object data){
+        for(DataGearManager dgm:dgmList.values()){
+            dgm.put(key, data);
+        }
+    }
+
 }
--- a/src/main/java/christie/datagear/dg/DataGear.java	Mon Jan 07 17:20:53 2019 +0900
+++ b/src/main/java/christie/datagear/dg/DataGear.java	Tue Jan 08 19:03:33 2019 +0900
@@ -45,6 +45,9 @@
             }
         }
 
+        // ごめん. いい例外処理見つけられなかった.
+        throw new ClassCastException("datagear cannot set class from " + dataClazz.getName() + " to " + clazz.getName());
+
     }
 
     public void setClazz(Class clazz){
--- a/src/main/java/christie/test/Paxos/AcceptCodeGear.java	Mon Jan 07 17:20:53 2019 +0900
+++ b/src/main/java/christie/test/Paxos/AcceptCodeGear.java	Tue Jan 08 19:03:33 2019 +0900
@@ -1,13 +1,28 @@
 package christie.test.Paxos;
 
+import christie.annotation.Peek;
+import christie.annotation.Take;
 import christie.codegear.CodeGear;
 import christie.codegear.CodeGearManager;
 
 public class AcceptCodeGear extends CodeGear {
 
+    @Take
+    Proposal acceptProposal;
+
+    @Take
+    Proposal promisedProposal;
+
     @Override
     protected void run(CodeGearManager cgm) {
 
+        if(promisedProposal.getNumber() <= acceptProposal.getNumber()){
+            System.out.println("accept: " + acceptProposal.getValue());
+            put("acceptProposal", acceptProposal);
+            return;
+        }else{
+            put("promisedProposal", promisedProposal);
+        }
 
     }
 }
--- a/src/main/java/christie/test/Paxos/AcceptorCodeGear.java	Mon Jan 07 17:20:53 2019 +0900
+++ b/src/main/java/christie/test/Paxos/AcceptorCodeGear.java	Tue Jan 08 19:03:33 2019 +0900
@@ -7,7 +7,7 @@
 public class AcceptorCodeGear extends CodeGear {
 
     @Override
-    protected void run(CodeGearManager cgm) {//できるだけ並列に走らせるためにStartCodeGearには書かない
+    protected void run(CodeGearManager cgm) {
         cgm.setup(new PromiseCodeGear());
         put("promisedProposal", new Proposal());
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/christie/test/Paxos/LearnerCodeGear.java	Tue Jan 08 19:03:33 2019 +0900
@@ -0,0 +1,5 @@
+package christie.test.Paxos;
+
+public class LearnerCodeGear {
+
+}
--- a/src/main/java/christie/test/Paxos/PromiseCodeGear.java	Mon Jan 07 17:20:53 2019 +0900
+++ b/src/main/java/christie/test/Paxos/PromiseCodeGear.java	Tue Jan 08 19:03:33 2019 +0900
@@ -6,9 +6,6 @@
 
 public class PromiseCodeGear extends CodeGear {
 
-
-    Proposal acceptedProposal;
-
     @Take
     Proposal promisedProposal;
 
@@ -21,17 +18,20 @@
     @Override
     protected void run(CodeGearManager cgm) {
 
+        String proposerName = prepareProposal.getProposerName();
+
         if(promisedProposal.getNumber() < prepareProposal.getNumber()) {
-            String proposerName= prepareProposal.getProposerName();
             System.out.println("promised < prepare : " + promisedProposal.getNumber() +  " < " + prepareProposal.getNumber());
             System.out.println("Acceptor" + cgm.cgmID + " Recive Proposal from : " + proposerName);
-            getLocalDGM().put("promisedProposal", prepareProposal);
-            getDGM(proposerName).put("recievePromise", prepareProposal);
-            //cgm.setup(new AcceptCodeGear());
-        }else {
-            put("promisedProposal", promisedProposal);
+            promisedProposal = prepareProposal;
+
+            cgm.setup(new AcceptCodeGear());
+        }else{
+            System.out.println("cannot promiss " + proposerName);
         }
 
+        put("promisedProposal", promisedProposal);
+        put(proposerName,"receivePromise", promisedProposal);
         cgm.setup(new PromiseCodeGear());
     }
 
--- a/src/main/java/christie/test/Paxos/Proposal.java	Mon Jan 07 17:20:53 2019 +0900
+++ b/src/main/java/christie/test/Paxos/Proposal.java	Tue Jan 08 19:03:33 2019 +0900
@@ -28,6 +28,8 @@
         this.value = value;
     }
 
+    public int getValue(){ return this.value; }
+
     public int getNumber(){
         return this.number;
     }
--- a/src/main/java/christie/test/Paxos/ProposerCodeGear.java	Mon Jan 07 17:20:53 2019 +0900
+++ b/src/main/java/christie/test/Paxos/ProposerCodeGear.java	Tue Jan 08 19:03:33 2019 +0900
@@ -1,6 +1,7 @@
 package christie.test.Paxos;
 
 
+import christie.annotation.Peek;
 import christie.codegear.CodeGear;
 import christie.codegear.CodeGearManager;
 import christie.datagear.DataGearManager;
@@ -8,14 +9,22 @@
 import java.util.HashMap;
 
 public class ProposerCodeGear extends CodeGear {
+    @Peek
+    int id;
 
-    HashMap<String, DataGearManager> acceptors;
+    @Peek
+    String nodeName;
+
+    @Peek
+    int nodeNum;
 
     @Override
     protected void run(CodeGearManager cgm) {
 
         cgm.setup(new SendPrepareRequestCodeGear());
-        put("sendProposal", new Proposal());
+        cgm.setup(new ReceivePromiseCodeGear());
+        Proposal sendProposal = new Proposal(nodeName, nodeNum, id, id);
+        put("sendProposal", sendProposal);
         put("promiseCount", 0);
 
     }
--- a/src/main/java/christie/test/Paxos/ReceivePromiseCodeGear.java	Mon Jan 07 17:20:53 2019 +0900
+++ b/src/main/java/christie/test/Paxos/ReceivePromiseCodeGear.java	Tue Jan 08 19:03:33 2019 +0900
@@ -11,47 +11,36 @@
 
 public class ReceivePromiseCodeGear extends CodeGear{
     @Peek
-    ConcurrentHashMap<String, DataGearManager> acceptors;
+    int acceptorNodeNum;
 
-    @Peek
+    @Take
     Proposal sendedProposal;
 
     @Take
-    Proposal recievePromise;
+    Proposal receivePromise;
 
     @Take
     int promiseCount;
 
-    @Take
-    long startTimeMillis;
-
-    int timeOut_ms = 1 * 1000;
-
 
     @Override
     protected void run(CodeGearManager cgm) {
 
-        if(promiseCount > acceptors.size()/2){
-            System.out.println(cgm.cgmID + " Can send AcceptRequest");
-            return;
-        }
-
-        if(recievePromise.getNumber() == sendedProposal.getNumber()){
-            promiseCount = promiseCount + 1;
-
-        }
+        if(receivePromise.getNumber() == sendedProposal.getNumber()){
+            promiseCount++;
+            if(promiseCount > acceptorNodeNum/2){
+                cgm.setup(new SendAcceptRequestCodeGear());
+            }
+            put("sendedProposal", sendedProposal);
 
-        long endTimeMillis = System.currentTimeMillis();
-        if(endTimeMillis - startTimeMillis < timeOut_ms){
-            put("promiseCount", promiseCount);
-            put("recievePromise", new Proposal());
-            put("startTimeMillis", startTimeMillis);
-            cgm.setup(new ReceivePromiseCodeGear());
-
-        }else{
-            put("sendProposal", sendedProposal.getIncrementedProposal());
+        }else if(receivePromise.getNumber() > sendedProposal.getNumber()){
+            promiseCount = 0;
+            sendedProposal.incrementNumber();
+            put("sendProposal", sendedProposal);
             cgm.setup(new SendPrepareRequestCodeGear());
         }
 
+        put("promiseCount", promiseCount);
+        cgm.setup(new ReceivePromiseCodeGear());
     }
 }
--- a/src/main/java/christie/test/Paxos/SendAcceptRequestCodeGear.java	Mon Jan 07 17:20:53 2019 +0900
+++ b/src/main/java/christie/test/Paxos/SendAcceptRequestCodeGear.java	Tue Jan 08 19:03:33 2019 +0900
@@ -4,19 +4,15 @@
 import christie.annotation.Take;
 import christie.codegear.CodeGear;
 import christie.codegear.CodeGearManager;
-import christie.datagear.DataGearManager;
 
-import java.util.concurrent.ConcurrentHashMap;
 
 public class SendAcceptRequestCodeGear extends CodeGear {
+
     @Peek
-    ConcurrentHashMap<String, DataGearManager> acceptors;
-
-    @Take
     Proposal sendedProposal;
 
     @Override
     protected void run(CodeGearManager cgm) {
-        System.out.println("send Accept Request");
+        cgm.putAllDGM("acceptProposal", sendedProposal);
     }
 }
--- a/src/main/java/christie/test/Paxos/SendPrepareRequestCodeGear.java	Mon Jan 07 17:20:53 2019 +0900
+++ b/src/main/java/christie/test/Paxos/SendPrepareRequestCodeGear.java	Tue Jan 08 19:03:33 2019 +0900
@@ -10,21 +10,14 @@
 import java.util.concurrent.ConcurrentHashMap;
 
 public class SendPrepareRequestCodeGear extends CodeGear{
-    @Peek
-    HashMap<String, DataGearManager> acceptors;
 
     @Take
     Proposal sendProposal;
 
+
     @Override
     protected void run(CodeGearManager cgm) {
-        for (String acceptorName : acceptors.keySet()){
-            put(acceptorName,"prepareProposal", sendProposal);
-        }
-
+        cgm.putAllDGM("prepareProposal", sendProposal);
         put("sendedProposal", sendProposal);
-        put("promiseCount", 0);
-        put("startTimeMillis", System.currentTimeMillis());
-        cgm.setup(new ReceivePromiseCodeGear());
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/christie/test/Paxos/StartLocalPaxos.java	Tue Jan 08 19:03:33 2019 +0900
@@ -0,0 +1,56 @@
+package christie.test.Paxos;
+
+import christie.codegear.CodeGearManager;
+
+import christie.codegear.StartCodeGear;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+public class StartLocalPaxos extends StartCodeGear{
+
+    public StartLocalPaxos(CodeGearManager cgm) {
+        super(cgm);
+
+    }
+
+    public static void main(String args[]){
+        int proposer_port = 10000;
+        int proposers_num = 2;
+        int acceptor_port = proposer_port + proposers_num;
+        int acceptors_num = 3;
+
+        ArrayList<CodeGearManager> proposers = new ArrayList<>();
+        ArrayList<CodeGearManager> acceptors = new ArrayList<>();
+
+
+        for(int i = 0; i < acceptors_num; i++){
+            String nodeName = "acceptor" + i;
+            CodeGearManager acceptor = createCGM(acceptor_port + i);
+            acceptor.getLocalDGM().put("nodeName", nodeName);
+            acceptor.setup(new AcceptorCodeGear());
+            acceptors.add(acceptor);
+        }
+
+        for(int i = 0; i < proposers_num; i++){
+            String nodeName = "proposer" + i;
+            CodeGearManager proposer = createCGM(proposer_port + i);
+            proposer.getLocalDGM().put("nodeName", nodeName);
+            proposer.getLocalDGM().put("nodeNum", proposers_num + acceptors_num);
+            proposer.getLocalDGM().put("id", i);
+            proposer.getLocalDGM().put("acceptorNodeNum", acceptors_num);
+            proposers.add(proposer);
+        }
+
+
+        for(int i = 0; i < proposers_num; i++){
+
+            for(int j = 0; j < acceptors_num; j++){
+                proposers.get(i).createRemoteDGM("acceptor" + j, "localhost", acceptors.get(j).localPort);
+                acceptors.get(j).createRemoteDGM("proposer" + i, "localhost", proposers.get(i).localPort);
+            }
+            proposers.get(i).setup(new ProposerCodeGear());
+        }
+
+    }
+}
\ No newline at end of file
--- a/src/main/java/christie/test/Paxos/StartPaxos.java	Mon Jan 07 17:20:53 2019 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-package christie.test.Paxos;
-
-import christie.codegear.CodeGearManager;
-
-import christie.codegear.StartCodeGear;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-
-public class StartPaxos extends StartCodeGear{
-
-    public StartPaxos(CodeGearManager cgm) {
-        super(cgm);
-
-    }
-
-    public static void main(String args[]){
-        int proposer_port = 10000;
-        int proposers_num = 2;
-        int acceptor_port = proposer_port + proposers_num;
-        int acceptors_num = 3;
-
-
-
-        HashMap<String, CodeGearManager> proposers = new HashMap<>();
-        HashMap<String, CodeGearManager> acceptors = new HashMap<>();
-
-
-        for(int i = 0; i < acceptors_num; i++){
-            CodeGearManager acceptor = createCGM(acceptor_port + i);
-            String nodeName = "acceptor" + i;
-            acceptor.getLocalDGM().put("nodeName", nodeName);
-            acceptor.setup(new AcceptorCodeGear());
-            acceptors.put(nodeName, acceptor);
-        }
-
-        for(int i = 0; i < proposers_num; i++){
-            String nodeName = "proposer" + i;
-            CodeGearManager proposer = createCGM(proposer_port + i);
-            proposer.getLocalDGM().put("nodeName", "proposer" + i);
-            proposer.getLocalDGM().put("nodeNum", proposers_num + acceptors_num);
-            proposers.put(nodeName, proposer);
-        }
-
-
-        for(int i = 0; i < proposers_num; i++){
-
-            for(int j = 0; j < acceptors_num; j++){
-                proposers.get(i).createRemoteDGM("acceptor" + j, "localhost", acceptors.get(j).localPort);
-                acceptors.get(j).createRemoteDGM("proposer" + i, "localhost", proposers.get(i).localPort);
-            }
-            proposers.get(i).setup(new ProposerCodeGear());
-        }
-
-    }
-
-
-
-
-}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/christie/topology/manager/ConfigWaiter.java.orig	Tue Jan 08 19:03:33 2019 +0900
@@ -0,0 +1,41 @@
+package christie.topology.manager;
+
+
+import christie.annotation.Peek;
+import christie.annotation.Take;
+import christie.codegear.CodeGear;
+import christie.codegear.CodeGearManager;
+
+
+import java.util.LinkedList;
+
+public class ConfigWaiter extends CodeGear {
+
+    @Peek
+    LinkedList<String> waiterNodeNames;
+
+    @Take
+    String nodePrepareDone;
+
+    @Take
+    int nodeNum;
+
+    public ConfigWaiter() { }
+
+    @Override
+    protected void run(CodeGearManager cgm) {
+        nodeNum--;
+        if (nodeNum == 0) {
+            getLocalDGM().put("start", "start");
+            for (String nodeName: waiterNodeNames) getDGM(nodeName).put("start", "start");
+            getLocalDGM().put("startTime", System.currentTimeMillis());
+            getLocalDGM().put("running", true);
+
+            return;
+        }
+
+        cgm.setup(new ConfigWaiter());
+        getLocalDGM().put("nodeNum", nodeNum);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/test/java/christie/example/HelloWorld/HelloWorldCodeGear.java.orig	Tue Jan 08 19:03:33 2019 +0900
@@ -0,0 +1,18 @@
+package christie.example.HelloWorld;
+
+import christie.annotation.Take;
+import christie.codegear.CodeGear;
+import christie.codegear.CodeGearManager;
+
+public class HelloWorldCodeGear extends CodeGear {
+
+    @Take
+    String helloWorld;
+
+    @Override
+    protected void run(CodeGearManager cgm) {
+        System.out.print(helloWorld + " ");
+        if(helloWorld.equals("world")) return;
+        cgm.setup(new HelloWorldCodeGear());
+    }
+}