Skip to content

Commit

Permalink
Merge branch 'hardfork'
Browse files Browse the repository at this point in the history
# Conflicts:
#	build.gradle
  • Loading branch information
elonmusk committed Oct 12, 2021
2 parents 41fbed3 + 80c8354 commit ce4ddad
Show file tree
Hide file tree
Showing 18 changed files with 357 additions and 775 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ plugins {
}

group 'org.unichain'
version '2.0.1'
version '2.0.2'

apply plugin: 'java'
apply plugin: 'com.google.protobuf'
Expand Down
32 changes: 22 additions & 10 deletions src/main/java/org/unichain/core/Wallet.java
Original file line number Diff line number Diff line change
Expand Up @@ -427,8 +427,8 @@ public GrpcAPI.Return broadcastTransaction(Transaction signedTransaction) {
.build();
} catch (AccountResourceInsufficientException e) {
logger.error("Broadcast transaction {} failed, {}.", tx.getTransactionId(), e.getMessage());
return builder.setResult(false).setCode(response_code.BANDWITH_ERROR)
.setMessage(ByteString.copyFromUtf8("AccountResourceInsufficient error"))
return builder.setResult(false).setCode(response_code.NOT_ENOUGH_RESOURCE)
.setMessage(ByteString.copyFromUtf8("AccountResourceInsufficient error :" + e.getMessage()))
.build();
} catch (DupTransactionException e) {
logger.error("Broadcast transaction {} failed, {}.", tx.getTransactionId(), e.getMessage());
Expand Down Expand Up @@ -1441,31 +1441,37 @@ public FutureTokenPack getFutureToken(FutureTokenQuery query) {
Assert.isTrue(query.hasField(TOKEN_QR_FIELD_NAME), "missing token name");
Assert.isTrue(query.hasField(TOKEN_QR_FIELD_OWNER_ADDR), "missing owner address");

if(!query.hasField(TOKEN_QR_FIELD_PAGE_SIZE) || !query.hasField(TOKEN_QR_FIELD_PAGE_INDEX))
if(!query.hasField(TOKEN_QR_FIELD_PAGE_SIZE))
{
query = query.toBuilder()
.setPageSize(DEFAULT_PAGE_SIZE)
.build();
}

if(!query.hasField(TOKEN_QR_FIELD_PAGE_INDEX))
{
query = query.toBuilder()
.setPageIndex(DEFAULT_PAGE_INDEX)
.build();
}

query = query.toBuilder()
.setTokenName(query.getTokenName().toUpperCase())
.build();

Assert.isTrue(query.getPageSize() > 0 && query.getPageIndex() >=0 && query.getPageSize() <= MAX_PAGE_SIZE, "invalid paging info");

var acc = dbManager.getAccountStore().get(query.getOwnerAddress().toByteArray());
Assert.notNull(acc, "owner address not found: " + Wallet.encode58Check(query.getOwnerAddress().toByteArray()));
var summary = acc.getFutureTokenSummary(query.getTokenName());
Assert.notNull(summary, "not found token" + query.getTokenName());
Assert.isTrue(summary.getTotalDeal() > 0, "not found future token deal of" + query.getTokenName());

//validate query
int pageSize = query.getPageSize();
int pageIndex = query.getPageIndex();
if(pageSize <= 0 || pageIndex < 0)
throw new IllegalArgumentException("invalid paging info");

List<FutureTokenV2> deals = new ArrayList<>();

int pageSize = query.getPageSize();
int pageIndex = query.getPageIndex();
long start = pageIndex * pageSize;
long end = start + pageSize;
if(start >= summary.getTotalDeal()){
Expand Down Expand Up @@ -1507,18 +1513,24 @@ public FutureTokenPack getFutureToken(FutureTokenQuery query) {
public FuturePack getFuture(FutureQuery query) {
Assert.isTrue(query.hasField(FUTURE_QR_FIELD_OWNER_ADDR), "missing owner address");

if(!query.hasField(FUTURE_QR_FIELD_PAGE_SIZE) || !query.hasField(FUTURE_QR_FIELD_PAGE_INDEX))
if(!query.hasField(FUTURE_QR_FIELD_PAGE_SIZE))
{
query = query.toBuilder()
.setPageSize(DEFAULT_PAGE_SIZE)
.build();
}

if(!query.hasField(FUTURE_QR_FIELD_PAGE_INDEX))
{
query = query.toBuilder()
.setPageIndex(DEFAULT_PAGE_INDEX)
.build();
}

//validate query
int pageSize = query.getPageSize();
int pageIndex = query.getPageIndex();
Assert.isTrue(pageSize > 0 && pageIndex >=0, "invalid paging info");
Assert.isTrue(pageSize > 0 && pageIndex >=0 && pageSize <= MAX_PAGE_SIZE, "invalid paging info");

var acc = dbManager.getAccountStore().get(query.getOwnerAddress().toByteArray());
Assert.isTrue(acc != null, "not found future account : " + query.getOwnerAddress());
Expand Down
20 changes: 12 additions & 8 deletions src/main/java/org/unichain/core/actuator/TokenCreateActuator.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@
import org.unichain.core.capsule.TokenPoolCapsule;
import org.unichain.core.capsule.TransactionResultCapsule;
import org.unichain.core.capsule.utils.TransactionUtil;
import org.unichain.core.config.Parameter;
import org.unichain.core.db.Manager;
import org.unichain.core.exception.ContractExeException;
import org.unichain.core.exception.ContractValidateException;
import org.unichain.core.services.http.utils.Util;
import org.unichain.protos.Contract.CreateTokenContract;
import org.unichain.protos.Protocol.Transaction.Result.code;

import static org.unichain.core.config.Parameter.ChainConstant.TOKEN_MAX_TRANSFER_FEE;
import static org.unichain.core.config.Parameter.ChainConstant.TOKEN_MAX_TRANSFER_FEE_RATE;
import static org.unichain.core.config.Parameter.ChainConstant.*;
import static org.unichain.core.services.http.utils.Util.*;

@Slf4j(topic = "actuator")
Expand All @@ -62,8 +62,7 @@ public boolean execute(TransactionResultCapsule ret) throws ContractExeException
var startTime = capsule.getStartTime();
if(!ctx.hasField(TOKEN_CREATE_FIELD_END_TIME))
{
capsule.setEndTime(startTime + FIFTY_YEARS);
logger.info("default endTime to startTime + 10Years: " + capsule.getEndTime());
capsule.setEndTime(startTime + Parameter.ChainConstant.DEFAULT_TOKEN_AGE);
}

capsule.setBurnedToken(0L);
Expand Down Expand Up @@ -110,10 +109,15 @@ public boolean validate() throws ContractValidateException {
Assert.isTrue(TransactionUtil.validAssetDescription(ByteString.copyFrom(ctx.getDescription().getBytes()).toByteArray()), "Invalid description");

long startTime = ctx.hasField(TOKEN_CREATE_FIELD_START_TIME) ? ctx.getStartTime() : dbManager.getHeadBlockTimeStamp();
Assert.isTrue(startTime >= dbManager.getHeadBlockTimeStamp(), "Invalid start time");

long endTime = ctx.hasField(TOKEN_CREATE_FIELD_END_TIME) ? ctx.getEndTime() : startTime + FIFTY_YEARS;
Assert.isTrue(endTime > 0 && endTime > startTime && endTime > dbManager.getHeadBlockTimeStamp(), "Invalid end time");
long maxTokenActive = dbManager.getHeadBlockTimeStamp() + MAX_TOKEN_ACTIVE;
Assert.isTrue((startTime >= dbManager.getHeadBlockTimeStamp()) && (startTime <= maxTokenActive), "Invalid start time: must be greater than current block time and lower than limit timestamp:" +maxTokenActive);

long endTime = ctx.hasField(TOKEN_CREATE_FIELD_END_TIME) ? ctx.getEndTime() : (startTime + Parameter.ChainConstant.DEFAULT_TOKEN_AGE);
long maxTokenAge = dbManager.getHeadBlockTimeStamp() + MAX_TOKEN_AGE;
Assert.isTrue((endTime > 0)
&& (endTime > startTime )
&& (endTime > dbManager.getHeadBlockTimeStamp())
&& (endTime <= maxTokenAge) , "Invalid end time: must greater start time and lower than token age's limit timestamp:" + maxTokenAge);

Assert.isTrue(ctx.getTotalSupply() > 0 , "TotalSupply must greater than 0");
Assert.isTrue(ctx.getMaxSupply() > 0 , "MaxSupply must greater than 0!");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,8 @@ public boolean validate() throws ContractValidateException {

if (ctx.getAvailableTime() > 0) {
Assert.isTrue (ctx.getAvailableTime() > dbManager.getHeadBlockTimeStamp(), "block time passed available time");
Assert.isTrue (ctx.getAvailableTime() <= dbManager.getHeadBlockTimeStamp() + FIVE_YEARS, "available time limited within 5 years from now");
long maxAvailTime = dbManager.getHeadBlockTimeStamp() + dbManager.getMaxFutureTransferTimeDurationToken();
Assert.isTrue (ctx.getAvailableTime() <= maxAvailTime, "available time limited. Max available timestamp: " + maxAvailTime);
Assert.isTrue(ctx.getAvailableTime() < tokenPool.getEndTime(), "available time exceeded token expired time");
Assert.isTrue(ctx.getAmount() >= tokenPool.getLot(),"future transfer require minimum amount of : " + tokenPool.getLot());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import org.unichain.core.capsule.TransactionResultCapsule;
import org.unichain.core.config.Parameter.ChainConstant;
import org.unichain.core.db.Manager;
import org.unichain.core.exception.BalanceInsufficientException;
import org.unichain.core.exception.ContractExeException;
import org.unichain.core.exception.ContractValidateException;
import org.unichain.core.services.http.utils.Util;
Expand All @@ -26,8 +25,6 @@

@Slf4j(topic = "actuator")
public class TransferFutureActuator extends AbstractActuator {
private static final long FIVE_YEARS = 5 * 365 * 24 * 3600000;

TransferFutureActuator(Any contract, Manager dbManager) {
super(contract, dbManager);
}
Expand Down Expand Up @@ -74,7 +71,10 @@ public boolean validate() throws ContractValidateException {
var ownerAddress = ctx.getOwnerAddress().toByteArray();
var amount = ctx.getAmount();
Assert.isTrue(amount > 0, "Amount must greater than 0.");
Assert.isTrue(ctx.getExpireTime() > dbManager.getHeadBlockTimeStamp() && (ctx.getExpireTime() <= dbManager.getHeadBlockTimeStamp() + FIVE_YEARS), "expire time must greater current time, within five years from now");

long maxExpireTime = dbManager.getHeadBlockTimeStamp() + dbManager.getMaxFutureTransferTimeDurationUnw();
Assert.isTrue((ctx.getExpireTime() > dbManager.getHeadBlockTimeStamp()) && (ctx.getExpireTime() <= maxExpireTime),
"expire time must greater current block time, lower than maximum timestamp:" + maxExpireTime);
Assert.isTrue(Wallet.addressValid(ownerAddress), "Invalid ownerAddress");
Assert.isTrue(Wallet.addressValid(toAddress), "Invalid toAddress");
Assert.isTrue(!Arrays.equals(toAddress, ownerAddress), "Cannot transfer unw to yourself");
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/org/unichain/core/config/Parameter.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,19 @@ public class ChainConstant {
*/
public static final int BLOCK_VERSION = 1;
public static final int BLOCK_VERSION_2 = 2;

/**
* max unw/token transfer time range
*/
public static final long MAX_FUTURE_TRANSFER_TIME_RANGE_UNW = 10*31536000000L;//10 years
public static final long MAX_FUTURE_TRANSFER_UNW_TIME_RANGE_UPPER_BOUND = 30*31536000000L;//30 years

public static final long MAX_FUTURE_TRANSFER_TIME_RANGE_TOKEN = 10*31536000000L;//10 years
public static final long MAX_FUTURE_TRANSFER_TIME_RANGE_TOKEN_UPPER_BOUND = 30*31536000000L;//10 years

public static final long MAX_TOKEN_AGE = 50*31536000000L;//50 years
public static final long DEFAULT_TOKEN_AGE = 20*31536000000L;//20 years
public static final long MAX_TOKEN_ACTIVE = 50*31536000000L;//50 years
}

public class NodeConstant {
Expand Down
24 changes: 14 additions & 10 deletions src/main/java/org/unichain/core/db/BandwidthProcessorV2.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,19 @@ public void consume(TransactionCapsule tx, TransactionTrace trace) throws Contra
}

/**
* @todo review duplication of charging fee: this phase & actuator phase
* @todo double fee: this phase & actuator phase ?
*/
if (isContractCreateNewAccount(contract)){
if(contract.getType() == ContractType.TransferTokenContract)
consumeForCreateNewAccount4TokenTransfer(contract, trace);
else
consumeForCreateNewAccount(ownerAccountCap, trace);
continue;
try {
if (isContractCreateNewAccount(contract)) {
if (contract.getType() == ContractType.TransferTokenContract)
consumeForCreateNewAccount4TokenTransfer(contract, trace);
else
consumeForCreateNewAccount(ownerAccountCap, trace);
continue;
}
}
catch (AccountResourceInsufficientException ex){
throw new AccountResourceInsufficientException("Account Insufficient balance to create new account");
}

/**
Expand All @@ -114,9 +119,8 @@ public void consume(TransactionCapsule tx, TransactionTrace trace) throws Contra
continue;
break;
default:
if (useTransactionFee(ownerAccountCap, bytesSize, trace)) {
if (useTransactionFee(ownerAccountCap, bytesSize, trace))
continue;
}
break;
}
}
Expand All @@ -125,7 +129,7 @@ public void consume(TransactionCapsule tx, TransactionTrace trace) throws Contra
}

long fee = dbManager.getDynamicPropertiesStore().getTransactionFee() * bytesSize;
throw new AccountResourceInsufficientException("Account Insufficient bandwidth[" + bytesSize + "] and balance[" + fee + "] to create new account");
throw new AccountResourceInsufficientException("Account or token pool insufficient balance[" + fee + "]");
}
}

Expand Down
30 changes: 29 additions & 1 deletion src/main/java/org/unichain/core/db/DynamicPropertiesStore.java
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,10 @@ private static class DynamicResourceProperties {
private static final byte[] CURRENT_CYCLE_NUMBER = "CURRENT_CYCLE_NUMBER".getBytes();
private static final byte[] CHANGE_DELEGATION = "CHANGE_DELEGATION".getBytes();

//Future transfer unw/token
private static final byte[] MAX_FUTURE_TRANSFER_TIME_RANGE_UNW = "MAX_FUTURE_TRANSFER_TIME_RANGE_UNW".getBytes();
private static final byte[] MAX_FUTURE_TRANSFER_TIME_RANGE_TOKEN = "MAX_FUTURE_TRANSFER_TIME_RANGE_TOKEN".getBytes();

@Autowired
private DynamicPropertiesStore(@Value("properties") String dbName) {
super(dbName);
Expand Down Expand Up @@ -828,10 +832,17 @@ public long getWitnessStandbyAllowance() {
}

public void saveHardForkVersion(long blockVersion) {
logger.debug("HARD_FORK_VERSION:" + blockVersion);
this.put(HARD_FORK_VERSION, new BytesCapsule(ByteArray.fromLong(blockVersion)));
}

public void saveMaxFutureTransferUnw(long duration) {
this.put(MAX_FUTURE_TRANSFER_TIME_RANGE_UNW, new BytesCapsule(ByteArray.fromLong(duration)));
}

public void saveMaxFutureTransferToken(long duration) {
this.put(MAX_FUTURE_TRANSFER_TIME_RANGE_TOKEN, new BytesCapsule(ByteArray.fromLong(duration)));
}

/**
* @note
* - get block version
Expand Down Expand Up @@ -1590,6 +1601,23 @@ public long getLatestBlockHeaderTimestamp() {
() -> new IllegalArgumentException("not found latest block header timestamp"));
}

/**
* get timestamp of creating global latest block.
*/
public long getMaxFutureTransferTimeRangeUnw() {
return Optional.ofNullable(getUnchecked(MAX_FUTURE_TRANSFER_TIME_RANGE_UNW))
.map(BytesCapsule::getData)
.map(ByteArray::toLong)
.orElse(Parameter.ChainConstant.MAX_FUTURE_TRANSFER_TIME_RANGE_UNW);
}

public long getMaxFutureTransferTimeRangeToken() {
return Optional.ofNullable(getUnchecked(MAX_FUTURE_TRANSFER_TIME_RANGE_TOKEN))
.map(BytesCapsule::getData)
.map(ByteArray::toLong)
.orElse(Parameter.ChainConstant.MAX_FUTURE_TRANSFER_TIME_RANGE_TOKEN);
}

/**
* get number of global latest block.
*/
Expand Down
Loading

0 comments on commit ce4ddad

Please sign in to comment.