Skip to content

Commit

Permalink
Merge pull request #545 from nuls-io/2.3.0
Browse files Browse the repository at this point in the history
2.3.0
  • Loading branch information
lijunzhou committed Dec 22, 2019
2 parents 88ce05e + d4e3405 commit b3c917c
Show file tree
Hide file tree
Showing 22 changed files with 384 additions and 35 deletions.
66 changes: 66 additions & 0 deletions common/nuls-base/src/main/java/io/nuls/base/basic/AddressTool.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,72 @@ public class AddressTool {
private static final String ERROR_MESSAGE = "Address prefix can not be null!";
private static final String[] LENGTHPREFIX = new String[]{"", "a", "b", "c", "d", "e"};
private static final Map<Integer, byte[]> BLACK_HOLE_ADDRESS_MAP = new ConcurrentHashMap<>();
public static Set<String> BLOCK_HOLE_ADDRESS_SET = new HashSet<>();

static {
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgWAwX7MbvcFSLYqMoyn88d5x3AcUww");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgaXkFL7uYEhvC8zqjkYDNY5GQwrHos");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgdZh1GWTN7a6P92zThPC77EuDPt3N2");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgjVAEJi5ZZZs7hyrPt4xMv3uGTucGj");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgfSqGPCh97oXmGDD9rQqodNZbLivzc");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgiVWU4LMyQts6YXPFYsuQz8vDZss7J");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgfHVsVx1DYv9RouqKUyKnx6qwDtQMr");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgU1DEYKJMwMnvxQmwY9C4CAMFsEGov");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgX6CRCL8PnDU2rWCDWAo45Bv3nnHJa");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HghrwiGsdkvPLk6h3AmgiEayK9XgPcD");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgexB2yTuB3UEvo1z62V2XeHeksWnNf");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgTwwcmqb1AAxXFMjHQtwx5r96bjarV");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgZn6h34EdiPZW3uftAwktqaxEP7Jr1");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgYq9bZFPPYAT2AGfskNd2xBocE9DDG");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HggLHaWAgr57BzAujWujK7cnkdfUpDv");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgY2RHpL5qUzSZY3e5dDXTS7kKTwwkE");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgZn9PCmNMYEVLktW12NojNymk6JoFD");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgcjP6h7xbVgBzTXEWVKSZrAW5JMgEe");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HghNkGyb8XHcFrsLj9mdxyHB3dwqLYh");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgXjnzZjPQUqhxdsDnGQxinDPJ1wyUU");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HghLcS3B6kAc9929wSSX6F2gxTsCfjF");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgfUkXZduCFcWieYA1t9sieEnz7jjxL");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgeLcgDeAU3fJpwwf196kQdtJ6WhAyP");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgfTFrdqGCiB1SXZY5WZBjSUtgPLVCJ");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6Hggmxe4LDEcuYkfUVxJboJFdMA9vS2m");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgZfkCMz4oVMm2Dp9qPu53zL9XpMDGo");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgiW5AGRUqshNb6TqEZraRg1QUMaQ44");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgaFggHtSTyBA9H8uCJo14FEcivvXzf");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgiUvUtuyo2AK8xaXKBR7byo5AuK34T");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgiCnpKWd22i3FKqy4EZSRcvyDGKWNb");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgbvthvopoJjwcs8Y9xQbMTTgwLFjoz");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgeLxxtebLWDhTuULMHe1NFTPDo6swg");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6Hgd9RipQqzW19cpymhbLW1Pjeq4WkJA");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgaAqUVTRWGGsdz3AhzGKAshUbRQiKX");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6Hgeujp7b2Eox8TZzBHTfQYERzaMmCot");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgWQJbdYVjA3NUsrVP9g8hbvimJsKLr");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgjYpHJXbZ5mpzvRgG923nssNPRP188");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgWCZHGDuAHgRnJSjoLhXoDmPFv5Sbm");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgaYBps2XoqtGTJBp95Q3ET6M87oD36");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgX6tbavRbQBzYdiUAWG1BW8gzSmFq9");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgVtCN6CpceEKhRexa1zCJw6sXdBtqM");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HghSFFmFHPECZXrqv1Jo1ZmUZBbwuFM");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgdeVgSdz6653mWv6VdQeoUMkEuYGgi");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HggqMzNMQ1khS6sHxmPss79pCYPPEgS");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgfqCPU5AdwCbxQK62hd4q4USP27nAY");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgVwvoGs69TfvUNcPm5W4x9UYcW1QdR");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgXjfFD5HLYLm7vcNxjCM9x3iVZSvWR");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgfY5oVvjkCLz7vyBRdPQXppCcRxkCR");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6Hgd9mLzsEjGHFQ8igyzUEiGxCzG7mwg");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6Hgh3NYZAnsEqb83iYzzHrKxpZQNpbyS");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6Hgib3NyJWaGcNeMUyrAwBRhNp2zXYzi");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgaHjr4Z7GdnGc3vNLgFvXWP55hzNNX");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgZdGvSnxFPLHrLzpVzda4gtWvHKibT");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgZSxNKeFG7AwEL8MVDGZa1KwE39fPP");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgYLpfpPuZV9umGvYjJJX7EkKsUVukS");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgcCf8NfvCBjmdvDWbanWL5cFYiB8DM");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgZwFFYvEKppidUp7irjQFKADspQXaX");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgfNf8oRpKL8gsiFsR9ZwXVebHrcDAz");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgfuE7eRNu4wJrQV6fXKupuioL9cKri");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgWZmG6MSNighAjziatrvuhM1LpCF9o");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgbjaWQZrq3CoDZEed9RwAU3zyTeUAP");
BLOCK_HOLE_ADDRESS_SET.add("NULSd6HgawRRELcuKfvf4TeyidGLqFsHo9hgM");
}
/**
* chainId-地址映射表
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ public class SignatureUtil {
* @param tx 交易
*/
public static boolean validateTransactionSignture(Transaction tx) throws NulsException {
// 判断硬分叉,需要一个高度
long hardForkingHeight = 878000;
boolean forked = tx.getBlockHeight() <= 0 || tx.getBlockHeight() > hardForkingHeight;
try {
if (tx.getTransactionSignature() == null || tx.getTransactionSignature().length == 0) {
throw new NulsException(new Exception());
Expand All @@ -70,15 +73,24 @@ public static boolean validateTransactionSignture(Transaction tx) throws NulsExc
if ((transactionSignature.getP2PHKSignatures() == null || transactionSignature.getP2PHKSignatures().size() == 0)) {
throw new NulsException(new Exception("Transaction unsigned !"));
}
int signCount = tx.getCoinDataInstance().getFromAddressCount();
int passCount = 0;
for (P2PHKSignature signature : transactionSignature.getP2PHKSignatures()) {
if (!ECKey.verify(tx.getHash().getBytes(), signature.getSignData().getSignBytes(), signature.getPublicKey())) {
throw new NulsException(new Exception("Transaction signature error !"));
if (forked) {
//这里用硬分叉后的新逻辑
for (P2PHKSignature signature : transactionSignature.getP2PHKSignatures()) {
if (!ECKey.verify(tx.getHash().getBytes(), signature.getSignData().getSignBytes(), signature.getPublicKey())) {
throw new NulsException(new Exception("Transaction signature error !"));
}
}
passCount++;
if(passCount >= signCount){
break;
} else {
int signCount = tx.getCoinDataInstance().getFromAddressCount();
int passCount = 0;
for (P2PHKSignature signature : transactionSignature.getP2PHKSignatures()) {
if (!ECKey.verify(tx.getHash().getBytes(), signature.getSignData().getSignBytes(), signature.getPublicKey())) {
throw new NulsException(new Exception("Transaction signature error !"));
}
passCount++;
if (passCount >= signCount) {
break;
}
}
}
} else {
Expand All @@ -93,7 +105,7 @@ public static boolean validateTransactionSignture(Transaction tx) throws NulsExc
if (ECKey.verify(tx.getHash().getBytes(), signature.getSignData().getSignBytes(), signature.getPublicKey())) {
validCount++;
}
if (validCount >= transactionSignature.getM()) {
if (!forked && validCount >= transactionSignature.getM()) {
break;
}
}
Expand All @@ -114,9 +126,9 @@ public static boolean validateTransactionSignture(Transaction tx) throws NulsExc
*
* @param tx 交易
*/
public static boolean validateCtxSignture(Transaction tx)throws NulsException{
public static boolean validateCtxSignture(Transaction tx) throws NulsException {
if (tx.getTransactionSignature() == null || tx.getTransactionSignature().length == 0) {
if(tx.getType() == TxType.VERIFIER_INIT || tx.getType() == TxType.VERIFIER_CHANGE){
if (tx.getType() == TxType.VERIFIER_INIT || tx.getType() == TxType.VERIFIER_CHANGE) {
return true;
}
return false;
Expand Down
2 changes: 1 addition & 1 deletion module.ncf
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ blackHolePublicKey=0000000000000000000000000000000000000000000000000000000000000
port=8001
crossPort=8002
#魔法参数
packetMagic=20170904
packetMagic=20191222
#种子节点
selfSeedIps=seeda.nuls.io:8001,seedb.nuls.io:8001,seedc.nuls.io:8001,seedd.nuls.io:8001,seede.nuls.io:8001,seedf.nuls.io:8001
#主网的跨链种子连接节点
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ private void initDb() throws Exception {
RocksDBService.createTable(CHAIN_LATEST_HEIGHT);
RocksDBService.createTable(CHAIN_PARAMETERS);
RocksDBService.createTable(PROTOCOL_CONFIG);
RocksDBService.createTable(ROLLBACK_HEIGHT);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ public interface Constant {
* 存储每条链的配置信息
*/
String CHAIN_PARAMETERS = "chain_parameters";

String ROLLBACK_HEIGHT = "rollback_height";

/**
* 存储每条链的协议配置信息
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ public class BlockConfig extends ChainParameters implements ModuleConfig {
*/
private int testAutoRollbackAmount;

/**
* 回滚到指定高度
*/
private int rollbackHeight;

public int getNodesMonitorInterval() {
return nodesMonitorInterval;
}
Expand Down Expand Up @@ -162,4 +167,11 @@ public String getDataFolder() {
return dataPath + File.separator + ModuleE.BL.name;
}

public int getRollbackHeight() {
return rollbackHeight;
}

public void setRollbackHeight(int rollbackHeight) {
this.rollbackHeight = rollbackHeight;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package io.nuls.block.model;

import io.nuls.base.basic.NulsByteBuffer;
import io.nuls.base.basic.NulsOutputStreamBuffer;
import io.nuls.base.data.BaseNulsData;
import io.nuls.core.exception.NulsException;
import io.nuls.core.parse.SerializeUtils;

import java.io.IOException;

public class RollbackInfoPo extends BaseNulsData {
private long height;

public RollbackInfoPo(){
}

public RollbackInfoPo(long height){
this.height = height;
}

protected void serializeToStream(NulsOutputStreamBuffer stream) throws IOException {
stream.writeVarInt(height);
}

public void parse(NulsByteBuffer byteBuffer) throws NulsException {
this.height = byteBuffer.readVarInt();
}

public int size() {
return SerializeUtils.sizeOfVarInt(height);
}

public long getHeight() {
return height;
}

public void setHeight(long height) {
this.height = height;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ private boolean saveBlock(int chainId, Block block, boolean localInit, int downl
try {
TransactionCall.heightNotice(chainId, height);
CrossChainCall.heightNotice(chainId, height, RPCUtil.encode(block.getHeader().serialize()));
}catch (Exception e){
} catch (Exception e) {
LoggerUtil.COMMON_LOG.error(e);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package io.nuls.block.storage;

import io.nuls.block.model.RollbackInfoPo;

public interface RollbackStorageService {
public boolean save(RollbackInfoPo po, int chainId);

public RollbackInfoPo get(int chainId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package io.nuls.block.storage.impl;

import io.nuls.base.basic.NulsByteBuffer;
import io.nuls.block.constant.Constant;
import io.nuls.block.model.RollbackInfoPo;
import io.nuls.block.storage.RollbackStorageService;
import io.nuls.core.core.annotation.Component;
import io.nuls.core.model.ByteUtils;
import io.nuls.core.rockdb.service.RocksDBService;
import static io.nuls.block.utils.LoggerUtil.COMMON_LOG;

@Component
public class RollbackServiceImpl implements RollbackStorageService {
public boolean save(RollbackInfoPo po, int chainId) {
byte[] bytes;
try {
bytes = po.serialize();
return RocksDBService.put(Constant.ROLLBACK_HEIGHT, ByteUtils.intToBytes(chainId), bytes);
} catch (Exception e) {
COMMON_LOG.error("", e);
return false;
}
}

public RollbackInfoPo get(int chainId) {
try {
RollbackInfoPo po = new RollbackInfoPo();
byte[] bytes = RocksDBService.get(Constant.ROLLBACK_HEIGHT, ByteUtils.intToBytes(chainId));
if(bytes == null){
return null;
}
po.parse(new NulsByteBuffer(bytes));
return po;
} catch (Exception e) {
COMMON_LOG.error("", e);
return null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import io.nuls.block.rpc.call.TransactionCall;
import io.nuls.block.service.BlockService;
import io.nuls.block.storage.BlockStorageService;
import io.nuls.block.storage.RollbackStorageService;
import io.nuls.block.utils.BlockUtil;
import io.nuls.block.utils.ChainGenerator;
import io.nuls.core.core.ioc.SpringLiteContext;
Expand Down Expand Up @@ -160,6 +161,7 @@ public void run() {
}
}
}
rollbackToHeight(latestHeight, chainId);
}
while (true) {
if (synchronize()) {
Expand All @@ -173,6 +175,34 @@ public void run() {
}
}

/**
* 回滚区块到指定高度
* */
private void rollbackToHeight(long latestHeight, int chainId){
BlockConfig blockConfig = SpringLiteContext.getBean(BlockConfig.class);
long height = blockConfig.getRollbackHeight();
if(height > 0){
RollbackStorageService rollbackService = SpringLiteContext.getBean(RollbackStorageService.class);
RollbackInfoPo po = rollbackService.get(chainId);
if(po == null || po.getHeight() != height){
if(latestHeight > height + 1000){
ContextManager.getContext(chainId).getLogger().warn("If the rollback height is greater than 1000,p;ease replace the data package");
System.exit(1);
}
while (latestHeight >= height){
if(!blockService.rollbackBlock(chainId, latestHeight--, true)){
latestHeight++;
}
if ( latestHeight == 0) {
break;
}
}
po = new RollbackInfoPo(height);
rollbackService.save(po, chainId);
}
}
}

/**
* 等待网络稳定
* 每隔5秒请求一次getAvailableNodes,连续5次节点数大于minNodeAmount就认为网络稳定
Expand Down
1 change: 1 addition & 0 deletions module/nuls-block/src/main/resources/module.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"txGroupRequestorInterval": 1000,
"txGroupTaskDelay": 3000,
"testAutoRollbackAmount": 0,
"rollbackHeight": 878000,
"blockMaxSize": 5242880,
"resetTime": 1800000,
"chainSwtichThreshold": 3,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@ public interface ConsensusConstant {
* */
double RED_PUNISH_CREDIT_VAL = -1D;

long CHANGE_NET_HEIGHT_MIN = 878000;

long CHANGE_NET_HEIGHT_MAX = 900000;

/**
* 共识锁定时间
* */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,8 @@ public void punishTx(Chain chain, BlockHeader bestBlock, List<Transaction> txLis
if (null == member) {
member = round.getPreRound().getMemberByAgentAddress(address);
}
if (DoubleUtils.compare(member.getAgent().getRealCreditVal(), ConsensusConstant.RED_PUNISH_CREDIT_VAL) <= 0) {
boolean changeNet = bestBlock.getHeight() >= ConsensusConstant.CHANGE_NET_HEIGHT_MIN && bestBlock.getHeight() <= ConsensusConstant.CHANGE_NET_HEIGHT_MAX;
if (!changeNet && DoubleUtils.compare(member.getAgent().getRealCreditVal(), ConsensusConstant.RED_PUNISH_CREDIT_VAL) <= 0) {
if (!punishedSet.add(member.getPackingIndexOfRound())) {
continue;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import io.nuls.ledger.constant.LedgerErrorCode;
import io.nuls.ledger.model.ValidateResult;
import io.nuls.ledger.service.TransactionService;
import io.nuls.ledger.storage.Repository;
import io.nuls.ledger.utils.LoggerUtil;
import io.nuls.ledger.validator.CoinDataValidator;

Expand All @@ -56,6 +57,8 @@ public class ValidatorCmd extends BaseLedgerCmd {
CoinDataValidator coinDataValidator;
@Autowired
TransactionService transactionService;
@Autowired
Repository repository;

/**
* validate coin entity
Expand Down Expand Up @@ -91,10 +94,12 @@ public Response verifyCoinDataBatchPackaged(Map params) {
LoggerUtil.logger(chainId).debug("verifyCoinDataBatchPackaged response={}", parseResponse);
return parseResponse;
}
long packagingHeight = repository.getBlockHeight(chainId) + 1;
List<String> orphanList = new ArrayList<>();
List<String> successList = new ArrayList<>();
List<String> failList = new ArrayList<>();
for (Transaction tx : txList) {
tx.setBlockHeight(packagingHeight);
String txHash = tx.getHash().toHex();
ValidateResult validateResult = coinDataValidator.bathValidatePerTx(chainId, tx);
if (validateResult.isSuccess()) {
Expand Down
Loading

0 comments on commit b3c917c

Please sign in to comment.