Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions src/main/java/org/tron/common/utils/ForkController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package org.tron.common.utils;

import com.google.protobuf.ByteString;
import java.util.Arrays;
import java.util.List;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.tron.core.capsule.BlockCapsule;
import org.tron.core.capsule.TransactionCapsule;
import org.tron.core.config.Parameter.ChainConstant;
import org.tron.core.db.Manager;
import org.tron.protos.Protocol.Transaction.Contract.ContractType;

@Slf4j
@Component
public class ForkController {

public static final int DISCARD_SCOPE = ContractType.UpdateAssetContract.getNumber();

@Getter
private Manager manager;
private volatile int[] slots = new int[0];
private boolean forked;

public void init(Manager manager) {
this.manager = manager;
forked = manager.getDynamicPropertiesStore().getForked();
}

public synchronized boolean shouldBeForked() {
if (forked) {
logger.info("*****shouldBeForked:" + true);
return true;
}

for (int version : slots) {
if (version != ChainConstant.version) {
logger.info("*****shouldBeForked:" + false);
return false;
}
}

// todo add Maintenance or block number
forked = true;
manager.getDynamicPropertiesStore().forked();
logger.info("*****shouldBeForked:" + true);
return true;
}

public synchronized boolean forkOrNot(TransactionCapsule capsule) {
logger.info("*****forkOrNot:" + (shouldBeForked()
|| capsule.getInstance().getRawData().getContractList().get(0).getType().getNumber()
<= DISCARD_SCOPE));
return shouldBeForked()
|| capsule.getInstance().getRawData().getContractList().get(0).getType().getNumber()
<= DISCARD_SCOPE;
}

public synchronized void update(BlockCapsule blockCapsule) {
if (forked) {
return;
}

List<ByteString> witnesses = manager.getWitnessController().getActiveWitnesses();
if (witnesses.size() != slots.length) {
slots = new int[witnesses.size()];
}

ByteString witness = blockCapsule.getWitnessAddress();
int slot = witnesses.indexOf(witness);
if (slot < 0) {
return;
}
slots[slot] = blockCapsule.getInstance().getBlockHeader().getRawData().getVersion();

logger.info(
"*******update:" + Arrays.toString(slots)
+ ",witness size:" + witnesses.size()
+ "," + slots
+ ",slot:" + slot
+ ",version:" + blockCapsule.getInstance().getBlockHeader().getRawData().getVersion()
);
}

public void reset() {
Arrays.fill(slots, 0);
}

}
13 changes: 7 additions & 6 deletions src/main/java/org/tron/core/Wallet.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

import com.google.common.primitives.Longs;
import com.google.protobuf.ByteString;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
Expand Down Expand Up @@ -230,8 +229,7 @@ public static byte[] generateContractAddress(Transaction trx) {

}

public static byte[] generateContractAddress(byte[] ownerAddress,byte[] txRawDataHash) {

public static byte[] generateContractAddress(byte[] ownerAddress, byte[] txRawDataHash) {

byte[] combined = new byte[txRawDataHash.length + ownerAddress.length];
System.arraycopy(txRawDataHash, 0, combined, 0, txRawDataHash.length);
Expand All @@ -241,7 +239,7 @@ public static byte[] generateContractAddress(byte[] ownerAddress,byte[] txRawDat

}

public static byte[] generateContractAddress(byte[] transactionRootId, long nonce){
public static byte[] generateContractAddress(byte[] transactionRootId, long nonce) {
byte[] nonceBytes = Longs.toByteArray(nonce);
byte[] combined = new byte[transactionRootId.length + nonceBytes.length];
System.arraycopy(transactionRootId, 0, combined, 0, transactionRootId.length);
Expand Down Expand Up @@ -407,8 +405,11 @@ public GrpcAPI.Return broadcastTransaction(Transaction signaturedTransaction) {
dbManager.getTransactionIdCache().put(trx.getTransactionId(), true);
}

dbManager.pushTransaction(trx);
p2pNode.broadcast(message);
if (dbManager.getForkController().forkOrNot(trx)) {
dbManager.pushTransaction(trx);
p2pNode.broadcast(message);
}

return builder.setResult(true).setCode(response_code.SUCCESS).build();
} catch (ValidateSignatureException e) {
logger.info(e.getMessage());
Expand Down
5 changes: 4 additions & 1 deletion src/main/java/org/tron/core/capsule/BlockCapsule.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.tron.common.utils.Sha256Hash;
import org.tron.common.utils.Time;
import org.tron.core.capsule.utils.MerkleTree;
import org.tron.core.config.Parameter.ChainConstant;
import org.tron.core.exception.BadItemException;
import org.tron.core.exception.ValidateSignatureException;
import org.tron.protos.Protocol.Block;
Expand Down Expand Up @@ -128,7 +129,9 @@ public BlockCapsule(long number, Sha256Hash hash, long when, ByteString witnessA
.setNumber(number)
.setParentHash(hash.getByteString())
.setTimestamp(when)
.setWitnessAddress(witnessAddress).build();
.setVersion(ChainConstant.version)
.setWitnessAddress(witnessAddress)
.build();

// block header
BlockHeader.Builder blockHeaderBuild = BlockHeader.newBuilder();
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/tron/core/config/Parameter.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ interface ChainConstant {
int BLOCK_FILLED_SLOTS_NUMBER = 128;
int MAX_VOTE_NUMBER = 30;
int MAX_FROZEN_NUMBER = 1;

int version = 1;
}

interface NodeConstant {
Expand Down
17 changes: 15 additions & 2 deletions src/main/java/org/tron/core/db/DynamicPropertiesStore.java
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,15 @@ public class DynamicPropertiesStore extends TronStoreWithRevoking<BytesCapsule>

private static final byte[] STORAGE_EXCHANGE_TAX_RATE = "STORAGE_EXCHANGE_TAX_RATE".getBytes();

private static final byte[] FORK_CONTROLLER = "FORK_CONTROLLER".getBytes();

//This value is only allowed to be 0, 1, -1
private static final byte[] REMOVE_THE_POWER_OF_THE_GR = "REMOVE_THE_POWER_OF_THE_GR".getBytes();

//If the parameter is larger than 0, the contract is allowed to be created.
private static final byte[] ALLOW_CREATION_OF_CONTRACTS = "ALLOW_CREATION_OF_CONTRACTS".getBytes();
private static final byte[] ALLOW_CREATION_OF_CONTRACTS = "ALLOW_CREATION_OF_CONTRACTS"
.getBytes();


@Autowired
private DynamicPropertiesStore(@Value("properties") String dbName) {
Expand Down Expand Up @@ -918,7 +922,7 @@ public long getAllowCreationOfContracts() {
}

public boolean supportVM() {
return getAllowCreationOfContracts() == 1L;
return getAllowCreationOfContracts() == 1L;
}

public void saveBlockFilledSlots(int[] blockFilledSlots) {
Expand Down Expand Up @@ -1121,4 +1125,13 @@ public void addTotalTransactionCost(long fee) {
long newValue = getTotalTransactionCost() + fee;
saveTotalTransactionCost(newValue);
}

public void forked() {
put(FORK_CONTROLLER, new BytesCapsule(Boolean.toString(true).getBytes()));
}

public boolean getForked() {
byte[] value = revokingDB.getUnchecked(FORK_CONTROLLER);
return value == null ? Boolean.FALSE : Boolean.valueOf(new String(value));
}
}
35 changes: 29 additions & 6 deletions src/main/java/org/tron/core/db/Manager.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,15 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.*;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import javafx.util.Pair;
import javax.annotation.PostConstruct;
Expand All @@ -33,6 +41,7 @@
import org.tron.common.runtime.vm.program.invoke.ProgramInvokeFactoryImpl;
import org.tron.common.storage.DepositImpl;
import org.tron.common.utils.ByteArray;
import org.tron.common.utils.ForkController;
import org.tron.common.utils.SessionOptional;
import org.tron.common.utils.Sha256Hash;
import org.tron.common.utils.StringUtil;
Expand Down Expand Up @@ -172,6 +181,10 @@ public class Manager {
private Cache<Sha256Hash, Boolean> transactionIdCache = CacheBuilder
.newBuilder().maximumSize(100_000).recordStats().build();

@Getter
@Autowired
private ForkController forkController;

public WitnessStore getWitnessStore() {
return this.witnessStore;
}
Expand Down Expand Up @@ -364,6 +377,7 @@ public void init() {
Args.getInstance().getOutputDirectory());
System.exit(1);
}
forkController.init(this);
revokingStore.enable();

// this.codeStore = CodeStore.create("code");
Expand Down Expand Up @@ -1100,11 +1114,13 @@ public synchronized BlockCapsule generateBlock(
}
// apply transaction
try (ISession tmpSeesion = revokingStore.buildSession()) {
processTransaction(trx, null);
// trx.resetResult();
tmpSeesion.merge();
// push into block
blockCapsule.addTransaction(trx);
if (forkController.forkOrNot(trx)) {
processTransaction(trx, null);
// trx.resetResult();
tmpSeesion.merge();
// push into block
blockCapsule.addTransaction(trx);
}
iterator.remove();
} catch (ContractExeException e) {
logger.info("contract not processed during execute");
Expand Down Expand Up @@ -1301,6 +1317,12 @@ public void updateLatestSolidifiedBlock() {
}
getDynamicPropertiesStore().saveLatestSolidifiedBlockNum(latestSolidifiedBlockNum);
logger.info("update solid block, num = {}", latestSolidifiedBlockNum);
try {
BlockCapsule solidifiedBlock = getBlockByNum(latestSolidifiedBlockNum);
forkController.update(solidifiedBlock);
} catch (ItemNotFoundException | BadItemException e) {
logger.error("solidified block not found");
}
}

public long getSyncBeginNumber() {
Expand Down Expand Up @@ -1335,6 +1357,7 @@ private void processMaintenance(BlockCapsule block) {
proposalController.processProposals();
witnessController.updateWitness();
this.dynamicPropertiesStore.updateNextMaintenanceTime(block.getTimeStamp());
forkController.reset();
}

/**
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/org/tron/core/net/node/NodeDelegate.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,6 @@ Deque<BlockId> getBlockChainSummary(BlockId beginBLockId, Deque<BlockId> blockId
BlockCapsule getGenesisBlock();

boolean canChainRevoke(long num);

boolean forkOrNot(TransactionCapsule transactionCapsule);
}
5 changes: 5 additions & 0 deletions src/main/java/org/tron/core/net/node/NodeDelegateImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -389,4 +389,9 @@ public BlockCapsule getGenesisBlock() {
public boolean canChainRevoke(long num) {
return num >= dbManager.getSyncBeginNumber();
}

@Override
public boolean forkOrNot(TransactionCapsule transactionCapsule) {
return dbManager.getForkController().forkOrNot(transactionCapsule);
}
}
3 changes: 2 additions & 1 deletion src/main/java/org/tron/core/net/node/NodeImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -855,7 +855,8 @@ private void onHandleTransactionMessage(PeerConnection peer, TransactionMessage
peer.getNode().getHost());
return;
}
if(del.handleTransaction(trxMsg.getTransactionCapsule())){
if (del.forkOrNot(trxMsg.getTransactionCapsule())
&& del.handleTransaction(trxMsg.getTransactionCapsule())) {
broadcast(trxMsg);
}
} catch (TraitorPeerException e) {
Expand Down
1 change: 1 addition & 0 deletions src/main/protos/core/Tron.proto
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@ message BlockHeader {
int64 number = 7;
int64 witness_id = 8;
bytes witness_address = 9;
int32 version = 10;
}
raw raw_data = 1;
bytes witness_signature = 2;
Expand Down