Skip to content

Commit

Permalink
Merge pull request #62 from yggdrash/feature/validator-pbft-implemant…
Browse files Browse the repository at this point in the history
…ation

Feature/validator pbft implemantation
  • Loading branch information
Peter Ryu committed Feb 1, 2019
2 parents 606c24a + 3aec4ef commit d5da30e
Show file tree
Hide file tree
Showing 28 changed files with 2,393 additions and 74 deletions.
26 changes: 24 additions & 2 deletions yggdrash-core/src/main/java/io/yggdrash/core/blockchain/Block.java
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ public BlockBody getBody() {
return body;
}

public long getIndex() {
return this.header.getIndex();
}

public byte[] getHash() {
ByteArrayOutputStream bao = new ByteArrayOutputStream();

Expand All @@ -123,7 +127,7 @@ public byte[] getHash() {
return HashUtil.sha3(bao.toByteArray());
}

public String getHashHexString() {
public String getHashHex() {
return org.spongycastle.util.encoders.Hex.toHexString(this.getHash());
}

Expand All @@ -150,7 +154,7 @@ public byte[] getAddress() {
Arrays.copyOfRange(pubBytes, 1, pubBytes.length));
}

public String getAddressHexString() {
public String getAddressHex() {
return Hex.toHexString(getAddress());
}

Expand Down Expand Up @@ -298,6 +302,10 @@ public static Proto.Block toProtoBlock(Block block) {
}

public static Block toBlock(Proto.Block protoBlock) {
if (protoBlock == null || protoBlock.getSerializedSize() == 0) {
return null;
}

BlockHeader blockHeader = new BlockHeader(
protoBlock.getHeader().getChain().toByteArray(),
protoBlock.getHeader().getVersion().toByteArray(),
Expand All @@ -320,4 +328,18 @@ public static Block toBlock(Proto.Block protoBlock) {
return new Block(blockHeader, protoBlock.getSignature().toByteArray(), txBody);
}

public static long getBlockLengthInBytes(byte[] bytes) {
if (bytes == null || bytes.length <= HEADER_LENGTH + SIGNATURE_LENGTH) {
log.debug("Input bytes is not valid");
return 0L;
}

byte[] headerBytes = new byte[HEADER_LENGTH];
System.arraycopy(bytes, 0, headerBytes, 0, headerBytes.length);
BlockHeader header = new BlockHeader(headerBytes);
long bodyLength = header.getBodyLength();

return (long) HEADER_LENGTH + (long) SIGNATURE_LENGTH + bodyLength;
}

}
63 changes: 63 additions & 0 deletions yggdrash-core/src/main/proto/PBFT.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
syntax = "proto3";

import "Yggdrash.proto";
import "BlockChain.proto";
import "EBFT.proto";

option java_package = "io.yggdrash.proto";
option java_outer_classname = "PbftProto";

message PbftMessage {
string type = 1;
int64 viewNumber = 2;
int64 seqNumber = 3;
bytes hash = 4;
bytes clientId = 5;
bytes result = 6;
bytes signature = 7;
Block block = 8;
}

message PbftMessageList {
repeated PbftMessage pbftMessageList = 1;
}

message PbftMessageSet {
PbftMessage prePrepare = 1;
PbftMessageList prepareList = 2;
PbftMessageList commitList = 3;
}

message PbftBlock {
Block block = 1;
PbftMessageSet pbftMessageSet = 2;
}

message PbftBlockList {
repeated PbftBlock pbftBlock = 1;
}

message PbftStatus {
int64 index = 1;
PbftMessageList pbftMessageList = 2;
int64 timestamp = 3;
bytes signature = 4;
}

service PbftService {
rpc PingPongTime (PingTime) returns (PongTime) {
}

rpc exchangePbftStatus (PbftStatus) returns (PbftStatus) {
}

rpc getPbftBlockList (Offset) returns (PbftBlockList) {
}

rpc multicastPbftMessage (PbftMessage) returns (Empty) {
}

rpc multicastPbftBlock (PbftBlock) returns (Empty) {
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ public void testBlockClone() throws Exception {
Block block2 = block1.clone();
log.debug("block2=" + block2.toJsonObject());

assertThat(block1.getHashHexString()).isEqualTo(block2.getHashHexString());
assertThat(block1.getHashHex()).isEqualTo(block2.getHashHex());
assertThat(block1.toJsonObject().toString()).isEqualTo(block2.toJsonObject().toString());
assertThat(block1.getSignature()).isEqualTo(block2.getSignature());
}
Expand All @@ -151,11 +151,11 @@ public void testBlockKey() throws Exception {
assertThat(block1.getPubKey()).isEqualTo(block2.getPubKey());
assertThat(block1.getPubKey()).isEqualTo(wallet.getPubicKey());

log.debug("block1 author address=" + block1.getAddressHexString());
log.debug("block2 author address=" + block2.getAddressHexString());
log.debug("block1 author address=" + block1.getAddressHex());
log.debug("block2 author address=" + block2.getAddressHex());
log.debug("wallet address=" + wallet.getHexAddress());
assertThat(block1.getAddressHexString()).isEqualTo(block2.getAddressHexString());
assertThat(block1.getAddressHexString()).isEqualTo(wallet.getHexAddress());
assertThat(block1.getAddressHex()).isEqualTo(block2.getAddressHex());
assertThat(block1.getAddressHex()).isEqualTo(wallet.getHexAddress());
assertThat(block1.verify()).isTrue();
assertThat(block2.verify()).isTrue();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
import io.yggdrash.core.exception.NotValidateException;
import io.yggdrash.core.wallet.Wallet;
import io.yggdrash.validator.data.BlockConChain;
import io.yggdrash.validator.data.PbftBlockChain;
import org.spongycastle.crypto.InvalidCipherTextException;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
Expand Down Expand Up @@ -44,8 +46,15 @@ Block genesisBlock() {
}

@Bean
@ConditionalOnProperty(name = "yggdrash.validator.consensus.algorithm", havingValue = "ebft")
BlockConChain blockConChain(Block genesisBlock, DefaultConfig defaultConfig) {
return new BlockConChain(genesisBlock, defaultConfig);
}

@Bean
@ConditionalOnProperty(name = "yggdrash.validator.consensus.algorithm", havingValue = "pbft")
PbftBlockChain pbftBlockChain(Block genesisBlock, DefaultConfig defaultConfig) {
return new PbftBlockChain(genesisBlock, defaultConfig);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
public class BlockCon {
private static final Logger log = LoggerFactory.getLogger(BlockCon.class);

private static final boolean TEST_NO_VERIFY = false; // todo: delete when testing is finished
private static final int BLOCK_HEADER_LENGTH = 124;
private static final int SIGNATURE_LENGTH = 65;
private static final int MAX_VALIDATOR_COUNT = 100;
Expand Down Expand Up @@ -164,10 +163,6 @@ public List<String> getConsensusList() {
}

public static boolean verify(BlockCon blockCon) {
if (TEST_NO_VERIFY) {
return true;
}

if (blockCon == null) {
return false;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
/*
* Copyright 2019 Akashic Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.yggdrash.validator.data;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import io.yggdrash.common.util.JsonUtil;
import io.yggdrash.core.blockchain.Block;
import io.yggdrash.proto.PbftProto;
import io.yggdrash.proto.Proto;
import io.yggdrash.validator.data.pbft.PbftMessageSet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spongycastle.util.encoders.Hex;

import java.nio.charset.StandardCharsets;
import java.util.List;

public class PbftBlock {
private static final Logger log = LoggerFactory.getLogger(PbftBlock.class);

private final Block block;
private final PbftMessageSet pbftMessageSet;

public PbftBlock(Block block, PbftMessageSet pbftMessageSet) {
this.block = block;
this.pbftMessageSet = pbftMessageSet;
}

public PbftBlock(byte[] bytes) {
this(JsonUtil.parseJsonObject(new String(bytes, StandardCharsets.UTF_8)));
}

public PbftBlock(JsonObject jsonObject) {
this.block = new Block(jsonObject.get("block").getAsJsonObject());

JsonElement pbftMessageSetJsonElement = jsonObject.get("pbftMessageSet");
if (pbftMessageSetJsonElement != null) {
this.pbftMessageSet = new PbftMessageSet(pbftMessageSetJsonElement.getAsJsonObject());
} else {
this.pbftMessageSet = null;
}
}

public PbftBlock(PbftProto.PbftBlock protoBlock) {
this.block = Block.toBlock(protoBlock.getBlock());
this.pbftMessageSet = new PbftMessageSet(protoBlock.getPbftMessageSet());
}

public byte[] toBinary() {
return this.toJsonObject().toString().getBytes(StandardCharsets.UTF_8);
}

public long getIndex() {
return this.block.getIndex();
}

public byte[] getHash() {
return this.block.getHash();
}

public String getHashHex() {
return Hex.toHexString(getHash());
}

public byte[] getPrevBlockHash() {
return this.block.getHeader().getPrevBlockHash();
}

public Block getBlock() {
return block;
}

public PbftMessageSet getPbftMessageSet() {
return pbftMessageSet;
}

public static boolean verify(PbftBlock block) {
if (block == null || block.getBlock() == null || block.getPbftMessageSet() == null) {
return false;
}

if (block.getIndex() == 0) { // genesis block
if (block.getBlock().verify()) {
return true;
}
} else {
if (block.getBlock().verify()
&& block.getPbftMessageSet().verify(block.getPbftMessageSet())) {
return true;
}
}

return false;
}

public JsonObject toJsonObject() {
JsonObject jsonObject = new JsonObject();
jsonObject.add("block", this.block.toJsonObject());
if (this.pbftMessageSet != null) {
jsonObject.add("pbftMessageSet", this.pbftMessageSet.toJsonObject());
}
return jsonObject;
}

public static PbftProto.PbftBlock toProto(PbftBlock pbftBlock) {
Proto.Block protoBlock = pbftBlock.getBlock().toProtoBlock();
PbftProto.PbftMessageSet protoPbftMessageSet =
PbftMessageSet.toProto(pbftBlock.getPbftMessageSet());

PbftProto.PbftBlock.Builder protoPbftBlockBuilder = PbftProto.PbftBlock.newBuilder();
if (protoBlock != null) {
protoPbftBlockBuilder.setBlock(protoBlock);
}
if (protoPbftMessageSet != null) {
protoPbftBlockBuilder.setPbftMessageSet(protoPbftMessageSet);
}

return protoPbftBlockBuilder.build();
}

public static PbftProto.PbftBlockList toProtoList(List<PbftBlock> pbftBlockList) {
if (pbftBlockList == null) {
return null;
}

PbftProto.PbftBlockList.Builder protoPbftBlockListBuilder =
PbftProto.PbftBlockList.newBuilder();
for (PbftBlock pbftBlock : pbftBlockList) {
protoPbftBlockListBuilder.addPbftBlock(PbftBlock.toProto(pbftBlock));
}

return protoPbftBlockListBuilder.build();
}

}
Loading

0 comments on commit d5da30e

Please sign in to comment.