Skip to content
Snippets Groups Projects
Commit a09032f1 authored by Benoit Lavenier's avatar Benoit Lavenier
Browse files

Start implementation of Duniter 0.2 :

 - wot/add
 - blockchain/membership
parent 1a900986
No related branches found
No related tags found
No related merge requests found
Showing
with 639 additions and 160 deletions
Running live reload server: undefined
Watching: 0=www/**/*, 1=!www/lib/**/*
Running dev server:  http://localhost:8100
Ionic server commands, enter:
restart or r to restart the client app from the root
goto or g and a url to have the app navigate to the given url
consolelogs or c to enable/disable console log output
serverlogs or s to enable/disable server log output
quit or q to shutdown the server and exit
ionic $ Ionic server commands, enter:
restart or r to restart the client app from the root
goto or g and a url to have the app navigate to the given url
consolelogs or c to enable/disable console log output
serverlogs or s to enable/disable server log output
quit or q to shutdown the server and exit
ionic $
\ No newline at end of file
......@@ -39,29 +39,31 @@ public class BlockchainBlock implements Serializable {
private String version;
private Integer nonce;
private Integer powMin;
private Integer number;
private Integer powMin;
private Integer time;
private Integer medianTime;
private Integer membersCount;
private BigInteger monetaryMass;
private Integer unitBase;
private String currency;
private String issuer;
private String signature;
private String hash;
private String parameters;
private String previousHash;
private String previousIssuer;
private String inner_hash;
private BigInteger dividend;
private String[] membersChanges;
private Identity[] identities;
private Joiner[] joiners;
private String[] actives;
private String[] leavers;
private Joiner[] leavers;
private Joiner[] actives;
private Revoked[] revoked;
private String[] excluded;
private String[] certifications;
// private int actives": [],
// private int transactions": [],
private Transaction[] transactions;
private String signature;
// raw": "Version: 1\nType: Block\nCurrency: zeta_brouzouf\nNonce: 8233\nNumber: 1\nDate: 1416589860\nConfirmedDate: 1416589860\nIssuer: HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk\nPreviousHash: 00006CD96A01378465318E48310118AC6B2F3625\nPreviousIssuer: HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk\nMembersCount: 4\nIdentities:\nJoiners:\nActives:\nLeavers:\nExcluded:\nCertifications:\nTransactions:\n"
//private String raw;
......@@ -181,9 +183,74 @@ public class BlockchainBlock implements Serializable {
this.joiners = joiners;
}
public Integer getUnitBase() {
return unitBase;
}
public void setUnitBase(Integer unitBase) {
this.unitBase = unitBase;
}
public String getInnerHash() {
return inner_hash;
}
public void setInnerHash(String inner_hash) {
this.inner_hash = inner_hash;
}
public Joiner[] getLeavers() {
return leavers;
}
public void setLeavers(Joiner[] leavers) {
this.leavers = leavers;
}
public Joiner[] getActives() {
return actives;
}
public void setActives(Joiner[] actives) {
this.actives = actives;
}
public Revoked[] getRevoked() {
return revoked;
}
public void setRevoked(Revoked[] revoked) {
this.revoked = revoked;
}
public String[] getExcluded() {
return excluded;
}
public void setExcluded(String[] excluded) {
this.excluded = excluded;
}
public String[] getCertifications() {
return certifications;
}
public void setCertifications(String[] certifications) {
this.certifications = certifications;
}
public Transaction[] getTransactions() {
return transactions;
}
public void setTransactions(Transaction[] transactions) {
this.transactions = transactions;
}
public String toString() {
String s = "version=" + version;
s += "\nnonce=" + nonce;
s += "\ninner_hash=" + inner_hash;
s += "\nnumber=" + number;
s += "\npowMin" + powMin;
s += "\ntime=" + time;
......@@ -199,11 +266,6 @@ public class BlockchainBlock implements Serializable {
s += "\npreviousIssuer=" + previousIssuer;
s += "\ndividend=" + dividend;
s += "\nmembersChanges:";
if (membersChanges != null) {
for (String m : membersChanges) {
s += "\n\t" + m;
}
}
s += "\nidentities:";
if (identities != null) {
for (Identity i : identities) {
......@@ -216,10 +278,22 @@ public class BlockchainBlock implements Serializable {
s += "\n\t" + j.toString();
}
}
s += "\nactives:";
if (actives != null) {
for (Joiner a : actives) {
s += "\n\t" + a.toString();
}
}
s += "\nleavers:";
if (leavers != null) {
for (String l : leavers) {
s += "\n\t" + l;
for (Joiner l : leavers) {
s += "\n\t" + l.toString();
}
}
s += "\nrevoked:";
if (leavers != null) {
for (Revoked r : revoked) {
s += "\n\t" + r.toString();
}
}
s += "\nexcluded:";
......@@ -242,20 +316,20 @@ public class BlockchainBlock implements Serializable {
private static final long serialVersionUID = 8080689271400316984L;
private String pubkey;
private String publicKey;
private String signature;
private String uid;
private String blockUid;
private long timestamp = -1;
private String userId;
public String getPubkey() {
return pubkey;
public String getPublicKey() {
return publicKey;
}
public void setPubkey(String pubkey) {
this.pubkey = pubkey;
public void setPublicKey(String publicKey) {
this.publicKey = publicKey;
}
public String getSignature() {
......@@ -266,29 +340,30 @@ public class BlockchainBlock implements Serializable {
this.signature = signature;
}
public String getUid() {
return uid;
public String getUserId() {
return userId;
}
public void setUid(String uid) {
this.uid = uid;
public void setUserId(String uid) {
this.userId = uid;
}
public long getTimestamp() {
return timestamp;
public String getBlockUid() {
return blockUid;
}
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
public void setBlockUid(String blockUid) {
this.blockUid = blockUid;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder()
.append(":").append(pubkey)
.append(":").append(publicKey)
.append(":").append(signature)
.append(":").append(timestamp)
.append("").append(uid);
.append(":").append(blockUid)
.append("").append(userId);
return sb.toString();
}
......@@ -297,24 +372,23 @@ public class BlockchainBlock implements Serializable {
public static class Joiner extends Identity {
private static final long serialVersionUID = 8448049949323699700L;
private String pubkey;
private String signature;
private String publicKey;
private String uid;
private String signature;
private long timestamp = -1;
private String userId;
private String number;
private String mBlockUid;
private String hash;
private String iBlockUid;
public String getPubkey() {
return pubkey;
public String getPublicKey() {
return publicKey;
}
public void setPubkey(String pubkey) {
this.pubkey = pubkey;
public void setPublicKey(String pubkey) {
this.publicKey = pubkey;
}
public String getSignature() {
......@@ -325,49 +399,183 @@ public class BlockchainBlock implements Serializable {
this.signature = signature;
}
public String getUid() {
return uid;
public String getUserId() {
return userId;
}
public void setUserId(String uid) {
this.userId = uid;
}
public String getMBlockUid() {
return mBlockUid;
}
public void setUid(String uid) {
this.uid = uid;
public void setMBlockUid(String mBlockUid) {
this.mBlockUid = mBlockUid;
}
public long getTimestamp() {
return timestamp;
public String getIBlockUid() {
return iBlockUid;
}
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
public void setIBlockUid(String iBlockUid) {
this.iBlockUid = iBlockUid;
}
public String getNumber() {
return number;
@Override
public String toString() {
StringBuilder sb = new StringBuilder()
.append(":").append(publicKey)
.append(":").append(signature)
.append(":").append(mBlockUid)
.append(":").append(iBlockUid)
.append(":").append(userId);
return sb.toString();
}
}
public static class Revoked implements Serializable {
private String signature;
private String userId;
public void setNumber(String number) {
this.number = number;
public String getSignature() {
return signature;
}
public void setSignature(String signature) {
this.signature = signature;
}
public String getHash() {
return hash;
public String getUserId() {
return userId;
}
public void setHash(String hash) {
this.hash = hash;
public void setUserId(String userId) {
this.userId = userId;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder()
.append(":").append(pubkey)
.append(":").append(signature)
.append(":").append(number)
.append(":").append(hash)
.append(":").append(timestamp)
.append(":").append(uid);
.append(":").append(userId);
return sb.toString();
}
}
public class Transaction implements Serializable {
private static final long serialVersionUID = 1L;
private String[] signatures;
private String version;
private String currency;
private String[] issuers;
private String[] inputs;
private String[] unlocks;
private String[] outputs;
public String[] getSignatures() {
return signatures;
}
public void setSignatures(String[] signatures) {
this.signatures = signatures;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getCurrency() {
return currency;
}
public void setCurrency(String currency) {
this.currency = currency;
}
public String[] getIssuers() {
return issuers;
}
public void setIssuers(String[] issuers) {
this.issuers = issuers;
}
public String[] getInputs() {
return inputs;
}
public void setInputs(String[] inputs) {
this.inputs = inputs;
}
public String[] getUnlocks() {
return unlocks;
}
public void setUnlocks(String[] unlocks) {
this.unlocks = unlocks;
}
public String[] getOutputs() {
return outputs;
}
public void setOutputs(String[] outputs) {
this.outputs = outputs;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("\nsignatures:");
if (signatures != null) {
for (String e : signatures) {
sb.append("\n\t").append(e);
}
}
sb.append("\nversion: ").append(version);
sb.append("\ncurrency: ").append(currency);
sb.append("\nissuers:");
if (issuers != null) {
for (String e : issuers) {
sb.append("\n\t").append(e);
}
}
sb.append("\ninputs:");
if (inputs != null) {
for (String e : inputs) {
sb.append("\n\t").append(e);
}
}
sb.append("\nunlocks:");
if (unlocks != null) {
for (String e : unlocks) {
sb.append("\n\t").append(e);
}
}
sb.append("\noutputs:");
if (outputs != null) {
for (String e : outputs) {
sb.append("\n\t").append(e);
}
}
return sb.toString();
}
}
......
......@@ -53,27 +53,47 @@ public class BlockchainParameters implements Serializable{
private Long ud0;
/**
* Minimum delay between 2 identical certifications (same pubkeys)
* Minimum delay between 2 certifications of a same issuer, in seconds. Must be positive or zero.
*/
private Integer sigDelay;
private Integer sigPeriod;
/**
* Maximum age of a valid signature (in seconds) (e.g. 2629800)
* Maximum quantity of active certifications made by member.
*/
private Integer sigStock;
/**
* Maximum delay a certification can wait before being expired for non-writing.
*/
private Integer sigWindow;
/**
* Maximum age of a active signature (in seconds) (e.g. 2629800)
*/
private Integer sigValidity;
/**
* Minimum quantity of signatures to be part of the WoT (e.g. 3)
* Minimum quantity of signatures to be part of the WoT(e.g. 3)
*/
private Integer sigQty;
/**
* Minimum quantity of valid made certifications to be part of the WoT for distance rule
* Maximum delay an identity can wait before being expired for non-writing.
*/
private Integer idtyWindow;
/**
* Maximum delay a membership can wait before being expired for non-writing.
*/
private Integer msWindow;
/**
* Minimum percent of sentries to reach to match the distance rule
*/
private Integer sigWoT;
private Double xpercent;
/**
* Maximum age of a valid membership (in seconds)
* Maximum age of an active membership (in seconds)
*/
private Integer msValidity;
......@@ -139,14 +159,6 @@ public class BlockchainParameters implements Serializable{
this.ud0 = ud0;
}
public Integer getSigDelay() {
return sigDelay;
}
public void setSigDelay(Integer sigDelay) {
this.sigDelay = sigDelay;
}
public Integer getSigValidity() {
return sigValidity;
}
......@@ -163,13 +175,6 @@ public class BlockchainParameters implements Serializable{
this.sigQty = sigQty;
}
public Integer getSigWoT() {
return sigWoT;
}
public void setSigWoT(Integer sigWoT) {
this.sigWoT = sigWoT;
}
public Integer getMsValidity() {
return msValidity;
......@@ -227,6 +232,54 @@ public class BlockchainParameters implements Serializable{
this.percentRot = percentRot;
}
public Integer getSigPeriod() {
return sigPeriod;
}
public void setSigPeriod(Integer sigPeriod) {
this.sigPeriod = sigPeriod;
}
public Integer getSigStock() {
return sigStock;
}
public void setSigStock(Integer sigStock) {
this.sigStock = sigStock;
}
public Integer getSigWindow() {
return sigWindow;
}
public void setSigWindow(Integer sigWindow) {
this.sigWindow = sigWindow;
}
public Integer getIdtyWindow() {
return idtyWindow;
}
public void setIdtyWindow(Integer idtyWindow) {
this.idtyWindow = idtyWindow;
}
public Integer getMsWindow() {
return msWindow;
}
public void setMsWindow(Integer msWindow) {
this.msWindow = msWindow;
}
public Double getXpercent() {
return xpercent;
}
public void setXpercent(Double xpercent) {
this.xpercent = xpercent;
}
@Override
public String toString() {
return new StringBuilder()
......@@ -234,10 +287,14 @@ public class BlockchainParameters implements Serializable{
.append("\nc=").append(c)
.append("\ndt=").append(dt)
.append("\nud0=").append(ud0)
.append("\nsigDelay=").append(sigDelay)
.append("\nsigPeriod=").append(sigPeriod)
.append("\nsigStock=").append(sigStock)
.append("\nsigWindow=").append(sigWindow)
.append("\nsigValidity=").append(sigValidity)
.append("\nsigQty=").append(sigQty)
.append("\nsigWoT=").append(sigWoT)
.append("\nidtyWindow=").append(idtyWindow)
.append("\nmsWindow=").append(msWindow)
.append("\nxpercent=").append(xpercent)
.append("\nmsValidity=").append(msValidity)
.append("\nstepMax=").append(stepMax)
.append("\nmedianTimeBlocks=").append(medianTimeBlocks)
......
package io.ucoin.ucoinj.core.client.model.bma;
import java.io.Serializable;
/**
* Created by blavenie on 31/03/16.
*/
public class Error implements Serializable {
private static final long serialVersionUID = -5598140972293478469L;
private int ucode;
private String message;
public int getUcode() {
return ucode;
}
public void setUcode(int ucode) {
this.ucode = ucode;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String toString() {
return "ucode=" + ucode
+ "\nmessage=" + message;
}
}
package io.ucoin.ucoinj.core.client.model.bma;
/**
* Created by blavenie on 31/03/16.
*/
public interface ErrorCode {
int UID_ALREADY_USED = 2002;
int MEMBERSHRIP_ALREADY_SEND = 2007;
}
......@@ -30,7 +30,6 @@ import java.io.Serializable;
public class NetworkPeering implements Serializable {
private String version;
private String currency;
private String status;
private String block;
private String signature;
// not need : private String raw
......@@ -54,14 +53,6 @@ public class NetworkPeering implements Serializable {
this.currency = currency;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getBlock() {
return block;
}
......@@ -87,7 +78,8 @@ public class NetworkPeering implements Serializable {
}
public String toString() {
String s = "currency=" + currency + "\n" +
String s = "version=" + version + "\n" +
"currency=" + currency + "\n" +
"pubkey=" + pubkey + "\n" +
"signature=" + signature + "\n" +
"block=" + block + "\n";
......
package io.ucoin.ucoinj.core.client.model.bma;
/**
* Created by blavenie on 31/03/16.
*/
public interface Protocol {
String VERSION = "2";
String TYPE_IDENTITY = "Identity";
String TYPE_MEMBERSHIP = "Membership";
String TYPE_TRANSACTION = "Transaction";
}
......@@ -97,6 +97,8 @@ public class WotLookup {
public String uid;
public Meta meta;
public String self;
public Boolean revoked;
public String revocation_sig;
public OtherSignature[] others;
public String getUid() {
......@@ -130,12 +132,36 @@ public class WotLookup {
public void setOthers(OtherSignature[] others) {
this.others = others;
}
public Boolean getRevoked() {
return revoked;
}
public void setRevoked(Boolean revoked) {
this.revoked = revoked;
}
public String getRevocationSig() {
return revocation_sig;
}
public void setRevocationSig(String revocationSig) {
this.revocation_sig = revocationSig;
}
}
public class Meta implements Serializable {
public Long timestamp;
public String timestamp;
public Long block_number;
public String getTimestamp() {
return timestamp;
}
public void setTimestamp(String timestamp) {
this.timestamp = timestamp;
}
}
public class OtherSignature {
......
......@@ -44,11 +44,11 @@ public class GsonUtils {
.setDateFormat(DATE_PATTERN)
// Register Multimap adapter
.registerTypeAdapter(Multimap.class, new MultimapTypeAdapter())
// Register Blockchain.identity adapter
// Register Blockchain.* adapter
.registerTypeAdapter(BlockchainBlock.Identity.class, new IdentityTypeAdapter())
// Register Blockchain.joiner adapter
.registerTypeAdapter(BlockchainBlock.Joiner.class, new JoinerTypeAdapter())
// Register endpoint adpater
.registerTypeAdapter(BlockchainBlock.Revoked.class, new RevokedTypeAdapter())
// Register endpoint adapter
.registerTypeAdapter(NetworkPeering.Endpoint.class, new EndpointAdapter())
;
}
......
......@@ -46,10 +46,10 @@ public class IdentityTypeAdapter implements JsonDeserializer<BlockchainBlock.Ide
BlockchainBlock.Identity result = new BlockchainBlock.Identity();
int i = 0;
result.setPubkey(identityParts[i++]);
result.setPublicKey(identityParts[i++]);
result.setSignature(identityParts[i++]);
result.setTimestamp(Integer.parseInt(identityParts[i++]));
result.setUid(identityParts[i++]);
result.setBlockUid(identityParts[i++]);
result.setUserId(identityParts[i++]);
return result;
}
......@@ -57,10 +57,10 @@ public class IdentityTypeAdapter implements JsonDeserializer<BlockchainBlock.Ide
@Override
public JsonElement serialize(BlockchainBlock.Identity identity, Type type, JsonSerializationContext context) {
String result = new StringBuilder()
.append(identity.getPubkey()).append(":")
.append(identity.getPublicKey()).append(":")
.append(identity.getSignature()).append(":")
.append(identity.getTimestamp()).append(":")
.append(identity.getUid()).toString();
.append(identity.getBlockUid()).append(":")
.append(identity.getUserId()).toString();
return context.serialize(result.toString(), String.class);
}
......
......@@ -24,7 +24,6 @@ package io.ucoin.ucoinj.core.client.model.bma.gson;
import com.google.gson.*;
import io.ucoin.ucoinj.core.client.model.Member;
import io.ucoin.ucoinj.core.client.model.bma.BlockchainBlock;
import org.apache.commons.lang3.StringUtils;
......@@ -40,19 +39,18 @@ public class JoinerTypeAdapter implements JsonDeserializer<BlockchainBlock.Joine
}
String[] identityParts = identityStr.split(":");
if (identityParts.length != 6) {
throw new JsonParseException(String.format("Bad format for BlockchainBlock.Identity. Should have 6 parts, but found %s.", identityParts.length));
if (identityParts.length != 5) {
throw new JsonParseException(String.format("Bad format for BlockchainBlock.Identity. Should have 5 parts, but found %s.", identityParts.length));
}
BlockchainBlock.Joiner result = new BlockchainBlock.Joiner();
int i = 0;
result.setPubkey(identityParts[i++]);
result.setPublicKey(identityParts[i++]);
result.setSignature(identityParts[i++]);
result.setNumber(identityParts[i++]);
result.setHash(identityParts[i++]);
result.setTimestamp(Integer.parseInt(identityParts[i++]));
result.setUid(identityParts[i++]);
result.setMBlockUid(identityParts[i++]);
result.setIBlockUid(identityParts[i++]);
result.setUserId(identityParts[i++]);
return result;
}
......@@ -60,12 +58,11 @@ public class JoinerTypeAdapter implements JsonDeserializer<BlockchainBlock.Joine
@Override
public JsonElement serialize(BlockchainBlock.Joiner member, Type type, JsonSerializationContext context) {
String result = new StringBuilder()
.append(member.getPubkey()).append(":")
.append(member.getPublicKey()).append(":")
.append(member.getSignature()).append(":")
.append(member.getNumber()).append(":")
.append(member.getHash()).append(":")
.append(member.getTimestamp()).append(":")
.append(member.getUid()).toString();
.append(member.getMBlockUid()).append(":")
.append(member.getIBlockUid()).append(":")
.append(member.getUserId()).toString();
return context.serialize(result.toString(), String.class);
}
......
package io.ucoin.ucoinj.core.client.model.bma.gson;
/*
* #%L
* UCoin Java Client :: Core API
* %%
* Copyright (C) 2014 - 2015 EIS
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #L%
*/
import com.google.gson.*;
import io.ucoin.ucoinj.core.client.model.bma.BlockchainBlock;
import org.apache.commons.lang3.StringUtils;
import java.lang.reflect.Type;
public class RevokedTypeAdapter implements JsonDeserializer<BlockchainBlock.Revoked>, JsonSerializer<BlockchainBlock.Revoked>{
@Override
public BlockchainBlock.Revoked deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
String identityStr = json.getAsString();
if (StringUtils.isBlank(identityStr)) {
return null;
}
String[] identityParts = identityStr.split(":");
if (identityParts.length != 4) {
throw new JsonParseException(String.format("Bad format for BlockchainBlock.Revoked. Should have 4 parts, but found %s.", identityParts.length));
}
BlockchainBlock.Revoked result = new BlockchainBlock.Revoked();
int i = 0;
result.setSignature(identityParts[i++]);
result.setUserId(identityParts[i++]);
return result;
}
@Override
public JsonElement serialize(BlockchainBlock.Revoked input, Type type, JsonSerializationContext context) {
String result = new StringBuilder()
.append(input.getSignature()).append(":")
.append(input.getUserId()).toString();
return context.serialize(result.toString(), String.class);
}
}
......@@ -29,21 +29,21 @@ public class Identity extends BasicIdentity {
private static final long serialVersionUID = -7451079677730158794L;
private long timestamp = -1;
private String timestamp = null;
private Boolean isMember = null;
private Long currencyId;
/**
* The timestamp value of the signature date
* The timestamp value of the signature date (a BLOCK_UID)
* @return
*/
public long getTimestamp() {
public String getTimestamp() {
return timestamp;
}
public void setTimestamp(long timestamp) {
public void setTimestamp(String timestamp) {
this.timestamp = timestamp;
}
......
......@@ -117,7 +117,7 @@ public class Wallet extends KeyPair implements LocalEntity, Serializable {
}
public boolean isSelfSend() {
return identity.getTimestamp() != -1;
return identity.getTimestamp() != null;
}
public Long getCurrencyId() {
......@@ -174,11 +174,11 @@ public class Wallet extends KeyPair implements LocalEntity, Serializable {
identity.setUid(uid);
}
public long getCertTimestamp() {
public String getCertTimestamp() {
return identity.getTimestamp();
}
public void setCertTimestamp(long timestamp) {
public void setCertTimestamp(String timestamp) {
identity.setTimestamp(timestamp);
}
......
......@@ -25,6 +25,7 @@ package io.ucoin.ucoinj.core.client.service;
import com.google.gson.Gson;
import io.ucoin.ucoinj.core.beans.InitializingBean;
import io.ucoin.ucoinj.core.client.config.Configuration;
import io.ucoin.ucoinj.core.client.model.bma.Error;
import io.ucoin.ucoinj.core.client.model.bma.gson.GsonUtils;
import io.ucoin.ucoinj.core.client.model.local.Peer;
import io.ucoin.ucoinj.core.client.service.exception.HttpBadRequestException;
......@@ -191,7 +192,13 @@ public class HttpServiceImpl implements HttpService, Closeable, InitializingBean
case HttpStatus.SC_FORBIDDEN:
throw new TechnicalException("ucoinj.client.authentication");
case HttpStatus.SC_BAD_REQUEST:
throw new HttpBadRequestException("ucoinj.client.status" + response.getStatusLine().toString());
try {
Error error = (Error)parseResponse(response, Error.class);
throw new HttpBadRequestException(error);
}
catch(IOException e) {
throw new HttpBadRequestException("ucoinj.client.status" + response.getStatusLine().toString());
}
default:
throw new TechnicalException("ucoinj.client.status" + response.getStatusLine().toString());
}
......
......@@ -24,6 +24,7 @@ package io.ucoin.ucoinj.core.client.service.bma;
import io.ucoin.ucoinj.core.beans.InitializingBean;
import io.ucoin.ucoinj.core.beans.Service;
import io.ucoin.ucoinj.core.client.model.bma.Protocol;
import io.ucoin.ucoinj.core.client.model.local.Peer;
import io.ucoin.ucoinj.core.client.service.HttpService;
import io.ucoin.ucoinj.core.client.service.local.PeerService;
......@@ -40,8 +41,6 @@ public abstract class BaseRemoteServiceImpl implements Service, InitializingBean
protected HttpService httpService;
protected PeerService peerService;
public static final String PROTOCOL_VERSION = "1";
@Override
public void afterPropertiesSet() {
httpService = ServiceLocator.instance().getHttpService();
......
......@@ -197,6 +197,8 @@ public interface BlockchainRemoteService extends Service {
*/
void requestMembership(Wallet wallet);
void requestMembership(Peer peer, String currency, byte[] pubKey, byte[] secKey, String uid, String membershipBlockUid, String selfBlockUid);
BlockchainMemberships getMembershipByPubkeyOrUid(long currencyId, String uidOrPubkey);
BlockchainMemberships getMembershipByPubkeyOrUid(Peer peer, String uidOrPubkey);
......
......@@ -26,6 +26,7 @@ import io.ucoin.ucoinj.core.client.config.Configuration;
import io.ucoin.ucoinj.core.client.model.bma.BlockchainBlock;
import io.ucoin.ucoinj.core.client.model.bma.BlockchainMemberships;
import io.ucoin.ucoinj.core.client.model.bma.BlockchainParameters;
import io.ucoin.ucoinj.core.client.model.bma.Protocol;
import io.ucoin.ucoinj.core.client.model.bma.gson.JsonArrayParser;
import io.ucoin.ucoinj.core.client.model.local.Currency;
import io.ucoin.ucoinj.core.client.model.local.Identity;
......@@ -38,11 +39,11 @@ import io.ucoin.ucoinj.core.client.service.exception.UidAlreadyUsedException;
import io.ucoin.ucoinj.core.client.service.exception.UidMatchAnotherPubkeyException;
import io.ucoin.ucoinj.core.exception.TechnicalException;
import io.ucoin.ucoinj.core.service.CryptoService;
import io.ucoin.ucoinj.core.util.CollectionUtils;
import io.ucoin.ucoinj.core.util.ObjectUtils;
import io.ucoin.ucoinj.core.util.StringUtils;
import io.ucoin.ucoinj.core.util.cache.Cache;
import io.ucoin.ucoinj.core.util.cache.SimpleCache;
import io.ucoin.ucoinj.core.util.crypto.CryptoUtils;
import io.ucoin.ucoinj.core.util.websocket.WebsocketClientEndpoint;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
......@@ -364,13 +365,14 @@ public class BlockchainRemoteServiceImpl extends BaseRemoteServiceImpl implement
public void requestMembership(Wallet wallet) {
ObjectUtils.checkNotNull(wallet);
ObjectUtils.checkNotNull(wallet.getCurrencyId());
ObjectUtils.checkNotNull(wallet.getCertTimestamp());
BlockchainBlock block = getCurrentBlock(wallet.getCurrencyId());
// Compute membership document
String membership = getMembership(wallet,
block,
true /*sideIn*/);
true /*side in*/);
if (log.isDebugEnabled()) {
log.debug(String.format(
......@@ -396,6 +398,28 @@ public class BlockchainRemoteServiceImpl extends BaseRemoteServiceImpl implement
executeRequest(httpPost, String.class);
}
public void requestMembership(Peer peer, String currency, byte[] pubKey, byte[] secKey, String uid, String membershipBlockUid, String selfBlockUid) {
// http post /blockchain/membership
HttpPost httpPost = new HttpPost(getPath(peer, URL_MEMBERSHIP));
// compute the self-certification
String membership = getSignedMembership(currency, pubKey, secKey, uid, membershipBlockUid, selfBlockUid, true/*side in*/);
List<NameValuePair> urlParameters = new ArrayList<NameValuePair>();
urlParameters.add(new BasicNameValuePair("membership", membership));
try {
httpPost.setEntity(new UrlEncodedFormEntity(urlParameters));
}
catch(UnsupportedEncodingException e) {
throw new TechnicalException(e);
}
// Execute the request
executeRequest(httpPost, String.class);
}
public BlockchainMemberships getMembershipByPubkeyOrUid(long currencyId, String uidOrPubkey) {
String path = String.format(URL_MEMBERSHIP_SEARCH, uidOrPubkey);
......@@ -428,13 +452,12 @@ public class BlockchainRemoteServiceImpl extends BaseRemoteServiceImpl implement
) {
// Create the member ship document
String membership = getMembership(wallet.getUid(),
String membership = getUnsignedMembership( wallet.getCurrency(),
wallet.getPubKeyHash(),
wallet.getCurrency(),
block.getNumber(),
block.getHash(),
sideIn,
wallet.getCertTimestamp()
wallet.getUid(),
block.getNumber() + '-' + block.getHash(),
wallet.getCertTimestamp(),
sideIn
);
// Add signature
......@@ -585,7 +608,7 @@ public class BlockchainRemoteServiceImpl extends BaseRemoteServiceImpl implement
// Self certification not exists: make sure the cert time is cleaning
else {
identity.setTimestamp(-1);
identity.setTimestamp(null);
}
}
}
......@@ -593,7 +616,7 @@ public class BlockchainRemoteServiceImpl extends BaseRemoteServiceImpl implement
// UID and pubkey is a member: fine
else if (identity.getPubkey().equals(result.getPubkey())) {
identity.setMember(true);
identity.setTimestamp(result.getSigDate());
//FIXME identity.setTimestamp(result.getSigDate());
}
// Something wrong on pubkey : uid already used by anither pubkey !
......@@ -642,25 +665,52 @@ public class BlockchainRemoteServiceImpl extends BaseRemoteServiceImpl implement
return result;
}
private String getMembership(String uid,
String publicKey,
String currency,
long blockNumber,
String blockHash,
boolean sideIn,
long certificationTime
protected String getSignedMembership(String currency,
byte[] pubKey,
byte[] secKey,
String userId,
String membershipBlockUid,
String selfBlockUid,
boolean sideIn) {
// Compute the pub key hash
String pubKeyHash = CryptoUtils.encodeBase58(pubKey);
// Create the member ship document
String membership = getUnsignedMembership(currency,
pubKeyHash,
userId,
membershipBlockUid,
selfBlockUid,
sideIn
);
// Add signature
CryptoService cryptoService = ServiceLocator.instance().getCryptoService();
String signature = cryptoService.sign(membership, secKey);
return new StringBuilder().append(membership).append(signature)
.append('\n').toString();
}
protected String getUnsignedMembership(String currency,
String pubkey,
String userId,
String membershipBlockUid,
String selfBlockUid,
boolean sideIn
) {
StringBuilder result = new StringBuilder()
.append("Version: 1\n")
.append("Type: Membership\n")
.append("Currency: ").append(currency).append('\n')
.append("Issuer: ").append(publicKey).append('\n')
.append("Block: ").append(blockNumber).append('-').append(blockHash).append('\n')
.append("Membership: ").append(sideIn ? "IN" : "OUT").append('\n')
.append("UserID: ").append(uid).append('\n')
.append("CertTS: ").append(certificationTime).append('\n');
return result.toString();
// see https://github.com/ucoin-io/ucoin/blob/master/doc/Protocol.md#membership
return new StringBuilder()
.append("Version: ").append(Protocol.VERSION)
.append("\nType: ").append(Protocol.TYPE_MEMBERSHIP)
.append("\nCurrency: ").append(currency)
.append("\nIssuer: ").append(pubkey)
.append("\nBlock: ").append(membershipBlockUid)
.append("\nMembership: ").append(sideIn ? "IN" : "OUT")
.append("\nUserID: ").append(userId)
.append("\nCertTS: ").append(selfBlockUid)
.append("\n")
.toString();
}
private Integer getLastBlockNumberFromJson(final String json) {
......
......@@ -33,8 +33,8 @@ import io.ucoin.ucoinj.core.client.service.exception.InsufficientCreditException
public interface TransactionRemoteService extends Service {
String transfert(Wallet wallet, String destPubKey, long amount,
String comment) throws InsufficientCreditException;
String transfer(Wallet wallet, String destPubKey, long amount,
String comment) throws InsufficientCreditException;
TxSource getSources(long currencyId, String pubKey);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment