Add new items to Param

- Add COMPENSATION_REQUEST_MIN_AMOUNT and COMPENSATION_REQUEST_MAX_AMOUNT
As BSQ based validation values can change over time if BSQ value
rise we need to support that in the Params as well.

- Add validateParamValue to ChangeParamValidator
This commit is contained in:
Manfred Karrer 2018-10-04 20:28:17 -05:00
parent 5f43bea278
commit ccdac8e20b
No known key found for this signature in database
GPG key ID: 401250966A6B2C46
10 changed files with 174 additions and 15 deletions

View file

@ -37,6 +37,7 @@ import bisq.core.dao.governance.proposal.ProposalConsensus;
import bisq.core.dao.governance.proposal.ProposalListPresentation;
import bisq.core.dao.governance.proposal.ProposalWithTransaction;
import bisq.core.dao.governance.proposal.TxException;
import bisq.core.dao.governance.proposal.compensation.CompensationConsensus;
import bisq.core.dao.governance.proposal.compensation.CompensationProposalService;
import bisq.core.dao.governance.proposal.confiscatebond.ConfiscateBondProposalService;
import bisq.core.dao.governance.proposal.param.ChangeParamProposalService;
@ -487,4 +488,12 @@ public class DaoFacade implements DaoSetupService {
public boolean isUnlocking(BondedRole bondedRole) {
return bsqStateService.isUnlocking(bondedRole);
}
public Coin getMinCompensationRequestAmount() {
return CompensationConsensus.getMinCompensationRequestAmount(bsqStateService, periodService.getChainHeight());
}
public Coin getMaxCompensationRequestAmount() {
return CompensationConsensus.getMaxCompensationRequestAmount(bsqStateService, periodService.getChainHeight());
}
}

View file

@ -36,8 +36,8 @@ import static org.apache.commons.lang3.Validate.notEmpty;
@Slf4j
public class ProposalValidator {
private final BsqStateService bsqStateService;
private final PeriodService periodService;
protected final BsqStateService bsqStateService;
protected final PeriodService periodService;
@Inject
public ProposalValidator(BsqStateService bsqStateService, PeriodService periodService) {

View file

@ -18,6 +18,8 @@
package bisq.core.dao.governance.proposal.compensation;
import bisq.core.dao.governance.proposal.ProposalConsensus;
import bisq.core.dao.state.BsqStateService;
import bisq.core.dao.state.governance.Param;
import org.bitcoinj.core.Coin;
@ -25,11 +27,12 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
public class CompensationConsensus extends ProposalConsensus {
public static Coin getMinCompensationRequestAmount() {
return Coin.valueOf(1_000); // 10 BSQ
public static Coin getMinCompensationRequestAmount(BsqStateService bsqStateService, int chainHeadHeight) {
return Coin.valueOf(bsqStateService.getParamValue(Param.COMPENSATION_REQUEST_MIN_AMOUNT, chainHeadHeight));
}
static Coin getMaxCompensationRequestAmount() {
return Coin.valueOf(20_000_000); // 200 000 BSQ
public static Coin getMaxCompensationRequestAmount(BsqStateService bsqStateService, int chainHeadHeight) {
return Coin.valueOf(bsqStateService.getParamValue(Param.COMPENSATION_REQUEST_MAX_AMOUNT, chainHeadHeight));
}
}

View file

@ -29,8 +29,6 @@ import javax.inject.Inject;
import lombok.extern.slf4j.Slf4j;
import static bisq.core.dao.governance.proposal.compensation.CompensationConsensus.getMaxCompensationRequestAmount;
import static bisq.core.dao.governance.proposal.compensation.CompensationConsensus.getMinCompensationRequestAmount;
import static com.google.common.base.Preconditions.checkArgument;
import static org.apache.commons.lang3.Validate.notEmpty;
@ -54,10 +52,13 @@ public class CompensationValidator extends ProposalValidator {
compensationProposal.getAddress(); // throws AddressFormatException if wrong address
Coin requestedBsq = compensationProposal.getRequestedBsq();
checkArgument(requestedBsq.compareTo(getMaxCompensationRequestAmount()) <= 0,
"Requested BSQ must not exceed MaxCompensationRequestAmount");
checkArgument(requestedBsq.compareTo(getMinCompensationRequestAmount()) >= 0,
"Requested BSQ must not be less than MinCompensationRequestAmount");
Coin maxCompensationRequestAmount = CompensationConsensus.getMaxCompensationRequestAmount(bsqStateService, periodService.getChainHeight());
checkArgument(requestedBsq.compareTo(maxCompensationRequestAmount) <= 0,
"Requested BSQ must not exceed " + (maxCompensationRequestAmount.value / 100L) + " BSQ");
Coin minCompensationRequestAmount = CompensationConsensus.getMinCompensationRequestAmount(bsqStateService, periodService.getChainHeight());
checkArgument(requestedBsq.compareTo(minCompensationRequestAmount) >= 0,
"Requested BSQ must not be less than " + (minCompensationRequestAmount.value / 100L) + " BSQ");
} catch (Throwable throwable) {
throw new ValidationException(throwable);
}

View file

@ -0,0 +1,24 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq 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 Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.core.dao.governance.proposal.param;
public class ChangeParamValidationException extends RuntimeException {
public ChangeParamValidationException(String message) {
super(message);
}
}

View file

@ -17,16 +17,22 @@
package bisq.core.dao.governance.proposal.param;
import bisq.core.btc.wallet.Restrictions;
import bisq.core.dao.exceptions.ValidationException;
import bisq.core.dao.governance.proposal.Proposal;
import bisq.core.dao.governance.proposal.ProposalValidator;
import bisq.core.dao.state.BsqStateService;
import bisq.core.dao.state.governance.Param;
import bisq.core.dao.state.period.PeriodService;
import javax.inject.Inject;
import com.google.common.annotations.VisibleForTesting;
import lombok.extern.slf4j.Slf4j;
import static com.google.common.base.Preconditions.checkArgument;
@Slf4j
public class ChangeParamValidator extends ProposalValidator {
@ -41,9 +47,109 @@ public class ChangeParamValidator extends ProposalValidator {
super.validateDataFields(proposal);
ChangeParamProposal changeParamProposal = (ChangeParamProposal) proposal;
//TODO
validateParamValue(changeParamProposal.getParam(), changeParamProposal.getParamValue());
} catch (Throwable throwable) {
throw new ValidationException(throwable);
}
}
// TODO
public boolean validateParamValue(Param param, long paramValue) throws ChangeParamValidationException {
// max 4 times the current value. min 25% of current value as general boundaries
checkMinMax(param, paramValue, 300, -75);
switch (param) {
case UNDEFINED:
break;
case BSQ_MAKER_FEE_IN_PERCENT:
break;
case BSQ_TAKER_FEE_IN_PERCENT:
break;
case BTC_MAKER_FEE_IN_PERCENT:
break;
case BTC_TAKER_FEE_IN_PERCENT:
break;
case PROPOSAL_FEE:
break;
case BLIND_VOTE_FEE:
break;
case COMPENSATION_REQUEST_MIN_AMOUNT:
if (paramValue < Restrictions.getMinNonDustOutput().value)
throw new ChangeParamValidationException("Value must be larger as the dust limit of " + Restrictions.getMinNonDustOutput().value);
checkMinMax(param, paramValue, 100, -50);
break;
case COMPENSATION_REQUEST_MAX_AMOUNT:
checkMinMax(param, paramValue, 100, -50);
break;
case QUORUM_PROPOSAL:
break;
case QUORUM_COMP_REQUEST:
break;
case QUORUM_CHANGE_PARAM:
break;
case QUORUM_REMOVE_ASSET:
break;
case QUORUM_CONFISCATION:
break;
case THRESHOLD_PROPOSAL:
break;
case THRESHOLD_COMP_REQUEST:
break;
case THRESHOLD_CHANGE_PARAM:
break;
case THRESHOLD_REMOVE_ASSET:
break;
case THRESHOLD_CONFISCATION:
break;
case PHASE_UNDEFINED:
break;
case PHASE_PROPOSAL:
break;
case PHASE_BREAK1:
break;
case PHASE_BLIND_VOTE:
break;
case PHASE_BREAK2:
break;
case PHASE_VOTE_REVEAL:
break;
case PHASE_BREAK3:
break;
case PHASE_RESULT:
break;
case PHASE_BREAK4:
break;
}
return false;
}
private void checkMinMax(Param param, long paramValue, long maxPercentChange, long minPercentChange) throws ChangeParamValidationException {
long max = getNewValueByPercentChange(param, maxPercentChange);
if (paramValue > max)
throw new ChangeParamValidationException("Value must not be larger than " + max);
long min = getNewValueByPercentChange(param, minPercentChange);
if (paramValue < min)
throw new ChangeParamValidationException("Value must not be smaller than " + min);
}
/**
* @param param The param to change
* @param percentChange 100 means 100% more than current value -> 2 times current value. -50 means half of the current value
* @return The new value.
*/
//TODO add test
// TODO use multiplier to make it more intuitive? (4,4) means 4 times current value for max and divided by 4 to get min value)
@VisibleForTesting
long getNewValueByPercentChange(Param param, long percentChange) {
checkArgument(percentChange > -100, "percentChange must be bigger than -100");
return (getCurrentValue(param) * 100 * (100 + percentChange)) / 100;
}
private long getCurrentValue(Param param) {
return bsqStateService.getParamValue(param, periodService.getChainHeight());
}
}

View file

@ -54,6 +54,10 @@ public enum Param {
PROPOSAL_FEE(100), // 5 BSQ TODO change low dev
BLIND_VOTE_FEE(200), // 10 BSQ TODO change low dev
// As BSQ based validation values can change over time if BSQ value rise we need to support that in the Params as well
COMPENSATION_REQUEST_MIN_AMOUNT(1_000), // 10 BSQ
COMPENSATION_REQUEST_MAX_AMOUNT(10_000_000), // 100 000 BSQ
// Quorum for voting in BSQ stake
QUORUM_PROPOSAL(100), // 10 000 BSQ TODO change low dev value
QUORUM_COMP_REQUEST(100), // 10 000 BSQ TODO change low dev value

View file

@ -1205,6 +1205,11 @@ dao.param.PROPOSAL_FEE=Proposal fee
# suppress inspection "UnusedProperty"
dao.param.BLIND_VOTE_FEE=Voting fee
# suppress inspection "UnusedProperty"
dao.param.COMPENSATION_REQUEST_MIN_AMOUNT=Compensation request min. amount
# suppress inspection "UnusedProperty"
dao.param.COMPENSATION_REQUEST_MAX_AMOUNT=Compensation request max. amount
# suppress inspection "UnusedProperty"
dao.param.QUORUM_PROPOSAL=Required quorum for proposal
# suppress inspection "UnusedProperty"

View file

@ -32,7 +32,6 @@ import bisq.core.dao.governance.ballot.Ballot;
import bisq.core.dao.governance.ballot.vote.Vote;
import bisq.core.dao.governance.proposal.Proposal;
import bisq.core.dao.governance.proposal.ProposalType;
import bisq.core.dao.governance.proposal.compensation.CompensationConsensus;
import bisq.core.dao.governance.proposal.compensation.CompensationProposal;
import bisq.core.dao.governance.proposal.confiscatebond.ConfiscateBondProposal;
import bisq.core.dao.governance.proposal.param.ChangeParamProposal;
@ -204,7 +203,8 @@ public class ProposalDisplay {
requestedBsqTextField = addLabelInputTextField(gridPane, ++gridRow,
Res.get("dao.proposal.display.requestedBsq")).second;
BsqValidator bsqValidator = new BsqValidator(bsqFormatter);
bsqValidator.setMinValue(CompensationConsensus.getMinCompensationRequestAmount());
bsqValidator.setMinValue(daoFacade.getMinCompensationRequestAmount());
bsqValidator.setMaxValue(daoFacade.getMaxCompensationRequestAmount());
checkNotNull(requestedBsqTextField, "requestedBsqTextField must not be null");
requestedBsqTextField.setValidator(bsqValidator);
inputControls.add(requestedBsqTextField);

View file

@ -36,6 +36,7 @@ import bisq.core.dao.governance.proposal.Proposal;
import bisq.core.dao.governance.proposal.ProposalType;
import bisq.core.dao.governance.proposal.ProposalWithTransaction;
import bisq.core.dao.governance.proposal.TxException;
import bisq.core.dao.governance.proposal.param.ChangeParamValidator;
import bisq.core.dao.governance.role.BondedRole;
import bisq.core.dao.state.BsqStateListener;
import bisq.core.dao.state.blockchain.Block;
@ -85,6 +86,7 @@ public class MakeProposalView extends ActivatableView<GridPane, Void> implements
private final WalletsSetup walletsSetup;
private final P2PService p2PService;
private final PhasesView phasesView;
private final ChangeParamValidator changeParamValidator;
private final BSFormatter btcFormatter;
private final BsqFormatter bsqFormatter;
@ -109,6 +111,7 @@ public class MakeProposalView extends ActivatableView<GridPane, Void> implements
P2PService p2PService,
FeeService feeService,
PhasesView phasesView,
ChangeParamValidator changeParamValidator,
BSFormatter btcFormatter,
BsqFormatter bsqFormatter) {
this.daoFacade = daoFacade;
@ -116,6 +119,7 @@ public class MakeProposalView extends ActivatableView<GridPane, Void> implements
this.walletsSetup = walletsSetup;
this.p2PService = p2PService;
this.phasesView = phasesView;
this.changeParamValidator = changeParamValidator;
this.btcFormatter = btcFormatter;
this.bsqFormatter = bsqFormatter;
}
@ -288,6 +292,9 @@ public class MakeProposalView extends ActivatableView<GridPane, Void> implements
} catch (Throwable t) {
throw new ValidationException("paramValue is not a long value", t);
}
changeParamValidator.validateParamValue(selectedParam, paramValue);
//TODO add more custom param validation
return daoFacade.getParamProposalWithTransaction(proposalDisplay.nameTextField.getText(),
proposalDisplay.linkInputTextField.getText(),