Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve data structure, validation and performance #2556

Merged
merged 55 commits into from Mar 23, 2019
Merged
Show file tree
Hide file tree
Changes from 48 commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
2baced1
Only log if hashchain has been updated
ManfredKarrer Mar 18, 2019
45185d3
Fix incorrect maybeUpdateHashChain call
ManfredKarrer Mar 18, 2019
1160986
Add dao-testnet explorer, update testnet url
ManfredKarrer Mar 18, 2019
7748366
Add UNDEFINED enum entry to all dao enums to allow updates
ManfredKarrer Mar 18, 2019
b66c23f
Log time needed for rpc getBlock call
ManfredKarrer Mar 18, 2019
0198bf4
Merge branch 'master' into misc-dao-improvements
ManfredKarrer Mar 18, 2019
c961477
Add comment
ManfredKarrer Mar 18, 2019
4119113
Adjust THRESHOLD_CHANGE_PARAM and THRESHOLD_CONFISCATION
ManfredKarrer Mar 18, 2019
f411a16
Rename PRICE_NODE_OPERATOR to DATA_RELAY_NODE_OPERATOR
ManfredKarrer Mar 18, 2019
16d1b77
Add BTC_DONATION_ADDRESS_OWNER
ManfredKarrer Mar 18, 2019
d8e226e
Add BTC_DONATION_ADDRESS_OWNER translation string
ManfredKarrer Mar 18, 2019
c8b0e88
Fix incorrect maxIncrease value
ManfredKarrer Mar 18, 2019
3d5e109
Rename getMiningFeeAndTxSize to getBlindVoteMiningFeeAndTxSize
ManfredKarrer Mar 18, 2019
d86aa28
Make ARBITRATOR_FEE % based, Add more validations
ManfredKarrer Mar 18, 2019
3dc9939
Refactor ChangeParamValidator
ManfredKarrer Mar 19, 2019
d02609a
Refactor: Rename ValidationException to ProposalValidationException
ManfredKarrer Mar 19, 2019
dbf3eba
Use ProposalValidatorProvider to operate on concrete ProposalValidator
ManfredKarrer Mar 19, 2019
ff5d18a
Use block height of proposal tx if available
ManfredKarrer Mar 19, 2019
e673d6c
Merge branch 'master' into misc-dao-improvements
ManfredKarrer Mar 19, 2019
bf474a3
Change blind vote phase and vote reveal durations
ManfredKarrer Mar 19, 2019
aa8dc29
Change min/max factor for phase durations from 3 to 2
ManfredKarrer Mar 19, 2019
4157ce1
Increase bond for youtube operator
ManfredKarrer Mar 19, 2019
729d59b
Add 3 new roles, adjust bond amount
ManfredKarrer Mar 19, 2019
a47ba42
Fix comments
ManfredKarrer Mar 20, 2019
7eb414a
Change bond lock time from 60 days to 75 days
ManfredKarrer Mar 20, 2019
ac3374c
Remove requiredQuorum and requiredThreshold from EvaluatedProposal
ManfredKarrer Mar 20, 2019
3aa50a3
Store requiredBond and unlockTime in RoleProposal
ManfredKarrer Mar 20, 2019
13ca802
Add extraDataMap to BlindVote and Proposal
ManfredKarrer Mar 20, 2019
fb3ca06
Add ConsensusCritical to proposal validators
ManfredKarrer Mar 20, 2019
eb2975a
Dont' call updateBsqBalance while batch processing
ManfredKarrer Mar 20, 2019
2a23896
Change log levels, improve logging
ManfredKarrer Mar 20, 2019
c732ce8
Rename db file to enforce usage of new file with new data structure
ManfredKarrer Mar 20, 2019
f780cf5
Add SHA3-256 hash function
ManfredKarrer Mar 21, 2019
735f619
Stream block batch processing on render frames
ManfredKarrer Mar 21, 2019
28c9367
Fix logging
ManfredKarrer Mar 21, 2019
e371fd4
Use ParamValidationException instead of AddressFormatException
ManfredKarrer Mar 21, 2019
81f4dd6
Add UNDEFINED entries
ManfredKarrer Mar 21, 2019
7651a94
Support exportToJson also for lite node
ManfredKarrer Mar 21, 2019
6d5b404
Remove SHA3-256 hash as it turned out it is slower as SHA256
ManfredKarrer Mar 21, 2019
c9ff5f7
Misc cleanups and refactorings
ManfredKarrer Mar 21, 2019
46f5b15
Update json export for vote results
ManfredKarrer Mar 21, 2019
7e61afc
Add BONDED_ROLE_FACTOR to param to react on BSQ price changes
ManfredKarrer Mar 22, 2019
92fdca2
Cleanup TODOs
ManfredKarrer Mar 22, 2019
49a0076
Don't support spending of pending BTC utxos in the BSQ wallet.
ManfredKarrer Mar 22, 2019
61a3be3
Remove nonBsqTxOutputMap from daoState
ManfredKarrer Mar 22, 2019
2ad86ab
Apply code inspection, cleanup
ManfredKarrer Mar 22, 2019
7b61429
Fix string
ManfredKarrer Mar 22, 2019
a9ef339
Merge branch 'master' into misc-dao-improvements
ManfredKarrer Mar 22, 2019
b20cb39
Update db files
ManfredKarrer Mar 22, 2019
f36678e
Add phaseChangeListener only after batch processing
ManfredKarrer Mar 22, 2019
68894ea
Update db files
ManfredKarrer Mar 22, 2019
954c5af
Use translation strings and show min/max values at change param valid…
ManfredKarrer Mar 22, 2019
26fd61d
Fix tests
ManfredKarrer Mar 22, 2019
43155b8
Fix % display
ManfredKarrer Mar 23, 2019
eb8feec
Add missing @EqualsAndHashCode(exclude = {"date"})
ManfredKarrer Mar 23, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
24 changes: 13 additions & 11 deletions common/src/main/proto/pb.proto
Expand Up @@ -1538,20 +1538,19 @@ message Cycle {
repeated DaoPhase dao_phase = 2;
}

message BsqState {
message DaoState {
int32 chain_height = 1;
// Because of the way how PB implements inheritence we need to use the super class as type
repeated BaseBlock blocks = 2;
repeated Cycle cycles = 3;
// Because of the way how PB implements inheritence we need to use the super class as type
map<string, BaseTxOutput> unspent_tx_output_map = 4;
map<string, BaseTxOutput> non_bsq_tx_output_map = 5;
map<string, Issuance> issuance_map = 6;
repeated string confiscated_lockup_tx_list = 7;
map<string, SpentInfo> spent_info_map = 8;
repeated ParamChange param_change_list = 9;
repeated EvaluatedProposal evaluated_proposal_list = 10;
repeated DecryptedBallotsWithMerits decrypted_ballots_with_merits_list = 11;
map<string, Issuance> issuance_map = 5;
repeated string confiscated_lockup_tx_list = 6;
map<string, SpentInfo> spent_info_map = 7;
repeated ParamChange param_change_list = 8;
repeated EvaluatedProposal evaluated_proposal_list = 9;
repeated DecryptedBallotsWithMerits decrypted_ballots_with_merits_list = 10;
}

message Issuance {
Expand All @@ -1577,6 +1576,8 @@ message Proposal {
GenericProposal generic_proposal = 11;
RemoveAssetProposal remove_asset_proposal = 12;
}
// We leave some index space here in case we add more subclasses
map<string, string> extra_data = 20;
}

message CompensationProposal {
Expand All @@ -1596,6 +1597,8 @@ message ChangeParamProposal {

message RoleProposal {
Role role = 1;
int64 required_bond_unit = 2;
int32 unlock_time = 3;
}

message ConfiscateBondProposal {
Expand Down Expand Up @@ -1707,6 +1710,7 @@ message BlindVote {
string tx_id = 2;
int64 stake = 3;
bytes encrypted_merit_list = 4;
map<string, string> extra_data = 5;
}

message MyBlindVoteList {
Expand Down Expand Up @@ -1748,8 +1752,6 @@ message ProposalVoteResult {
message EvaluatedProposal {
bool is_accepted = 1;
ProposalVoteResult proposal_vote_result = 2;
int64 required_quorum = 3;
int64 required_threshold = 4;
}

message DecryptedBallotsWithMerits {
Expand All @@ -1762,7 +1764,7 @@ message DecryptedBallotsWithMerits {
}

message DaoStateStore {
BsqState bsq_state = 1;
DaoState dao_state = 1;
repeated DaoStateHash dao_state_hash = 2;
}

Expand Down
5 changes: 3 additions & 2 deletions core/src/main/java/bisq/core/btc/wallet/BsqWalletService.java
Expand Up @@ -314,8 +314,9 @@ public Stream<Transaction> getPendingWalletTransactionsStream() {

private void updateBsqWalletTransactions() {
walletTransactions.setAll(getTransactions(false));
// walletTransactions.setAll(getBsqWalletTransactions());
updateBsqBalance();
if (daoStateService.isParseBlockChainComplete()) {
updateBsqBalance();
}
}

private Set<Transaction> getBsqWalletTransactions() {
Expand Down
Expand Up @@ -38,7 +38,7 @@ public class NonBsqCoinSelector extends BisqDefaultCoinSelector {

@Inject
public NonBsqCoinSelector(DaoStateService daoStateService) {
super(true);
super(false);
this.daoStateService = daoStateService;
}

Expand All @@ -49,13 +49,14 @@ protected boolean isTxOutputSpendable(TransactionOutput output) {
if (parentTransaction == null)
return false;

// It is important to not allow pending txs as otherwise unconfirmed BSQ txs would considered nonBSQ as
// below outputIsNotInBsqState would be true.
if (parentTransaction.getConfidence().getConfidenceType() != TransactionConfidence.ConfidenceType.BUILDING)
return false;

TxOutputKey key = new TxOutputKey(parentTransaction.getHashAsString(), output.getIndex());
// It might be that we received BTC in a non-BSQ tx so that will not be stored in out state and not found.
// So we consider any txOutput which is not in the state as BTC output.
boolean outputIsNotInBsqState = !daoStateService.existsTxOutput(key);
return outputIsNotInBsqState || daoStateService.getBtcTxOutput(key).isPresent();
return !daoStateService.existsTxOutput(key) || daoStateService.isRejectedIssuanceOutput(key);
}
}
84 changes: 52 additions & 32 deletions core/src/main/java/bisq/core/dao/DaoFacade.java
Expand Up @@ -19,7 +19,6 @@

import bisq.core.btc.exceptions.TransactionVerificationException;
import bisq.core.btc.exceptions.WalletException;
import bisq.core.dao.exceptions.ValidationException;
import bisq.core.dao.governance.ballot.BallotListPresentation;
import bisq.core.dao.governance.ballot.BallotListService;
import bisq.core.dao.governance.blindvote.BlindVoteConsensus;
Expand All @@ -30,7 +29,6 @@
import bisq.core.dao.governance.bond.reputation.BondedReputationRepository;
import bisq.core.dao.governance.bond.reputation.MyBondedReputation;
import bisq.core.dao.governance.bond.reputation.MyBondedReputationRepository;
import bisq.core.dao.governance.bond.reputation.MyReputationListService;
import bisq.core.dao.governance.bond.role.BondedRole;
import bisq.core.dao.governance.bond.role.BondedRolesRepository;
import bisq.core.dao.governance.bond.unlock.UnlockTxService;
Expand All @@ -41,6 +39,8 @@
import bisq.core.dao.governance.proposal.MyProposalListService;
import bisq.core.dao.governance.proposal.ProposalConsensus;
import bisq.core.dao.governance.proposal.ProposalListPresentation;
import bisq.core.dao.governance.proposal.ProposalService;
import bisq.core.dao.governance.proposal.ProposalValidationException;
import bisq.core.dao.governance.proposal.ProposalWithTransaction;
import bisq.core.dao.governance.proposal.TxException;
import bisq.core.dao.governance.proposal.compensation.CompensationConsensus;
Expand All @@ -55,16 +55,19 @@
import bisq.core.dao.state.DaoStateListener;
import bisq.core.dao.state.DaoStateService;
import bisq.core.dao.state.DaoStateStorageService;
import bisq.core.dao.state.model.blockchain.BaseTx;
import bisq.core.dao.state.model.blockchain.Block;
import bisq.core.dao.state.model.blockchain.Tx;
import bisq.core.dao.state.model.blockchain.TxOutput;
import bisq.core.dao.state.model.blockchain.TxOutputKey;
import bisq.core.dao.state.model.blockchain.TxType;
import bisq.core.dao.state.model.governance.Ballot;
import bisq.core.dao.state.model.governance.BondedRoleType;
import bisq.core.dao.state.model.governance.Cycle;
import bisq.core.dao.state.model.governance.DaoPhase;
import bisq.core.dao.state.model.governance.IssuanceType;
import bisq.core.dao.state.model.governance.Proposal;
import bisq.core.dao.state.model.governance.Role;
import bisq.core.dao.state.model.governance.RoleProposal;
import bisq.core.dao.state.model.governance.Vote;

import bisq.asset.Asset;
Expand Down Expand Up @@ -96,13 +99,16 @@

import javax.annotation.Nullable;

import static com.google.common.base.Preconditions.checkArgument;

/**
* Provides a facade to interact with the Dao domain. Hides complexity and domain details to clients (e.g. UI or APIs)
* by providing a reduced API and/or aggregating subroutines.
*/
@Slf4j
public class DaoFacade implements DaoSetupService {
private final ProposalListPresentation proposalListPresentation;
private final ProposalService proposalService;
private final BallotListService ballotListService;
private final BallotListPresentation ballotListPresentation;
private final MyProposalListService myProposalListService;
Expand All @@ -119,7 +125,6 @@ public class DaoFacade implements DaoSetupService {
private final RemoveAssetProposalFactory removeAssetProposalFactory;
private final BondedRolesRepository bondedRolesRepository;
private final BondedReputationRepository bondedReputationRepository;
private final MyReputationListService myReputationListService;
private final MyBondedReputationRepository myBondedReputationRepository;
private final LockupTxService lockupTxService;
private final UnlockTxService unlockTxService;
Expand All @@ -130,6 +135,7 @@ public class DaoFacade implements DaoSetupService {
@Inject
public DaoFacade(MyProposalListService myProposalListService,
ProposalListPresentation proposalListPresentation,
ProposalService proposalService,
BallotListService ballotListService,
BallotListPresentation ballotListPresentation,
DaoStateService daoStateService,
Expand All @@ -145,12 +151,12 @@ public DaoFacade(MyProposalListService myProposalListService,
RemoveAssetProposalFactory removeAssetProposalFactory,
BondedRolesRepository bondedRolesRepository,
BondedReputationRepository bondedReputationRepository,
MyReputationListService myReputationListService,
MyBondedReputationRepository myBondedReputationRepository,
LockupTxService lockupTxService,
UnlockTxService unlockTxService,
DaoStateStorageService daoStateStorageService) {
this.proposalListPresentation = proposalListPresentation;
this.proposalService = proposalService;
this.ballotListService = ballotListService;
this.ballotListPresentation = ballotListPresentation;
this.myProposalListService = myProposalListService;
Expand All @@ -167,7 +173,6 @@ public DaoFacade(MyProposalListService myProposalListService,
this.removeAssetProposalFactory = removeAssetProposalFactory;
this.bondedRolesRepository = bondedRolesRepository;
this.bondedReputationRepository = bondedReputationRepository;
this.myReputationListService = myReputationListService;
this.myBondedReputationRepository = myBondedReputationRepository;
this.lockupTxService = lockupTxService;
this.unlockTxService = unlockTxService;
Expand Down Expand Up @@ -228,7 +233,7 @@ public ObservableList<Proposal> getActiveOrMyUnconfirmedProposals() {
public ProposalWithTransaction getCompensationProposalWithTransaction(String name,
String link,
Coin requestedBsq)
throws ValidationException, InsufficientMoneyException, TxException {
throws ProposalValidationException, InsufficientMoneyException, TxException {
return compensationProposalFactory.createProposalWithTransaction(name,
link,
requestedBsq);
Expand All @@ -237,7 +242,7 @@ public ProposalWithTransaction getCompensationProposalWithTransaction(String nam
public ProposalWithTransaction getReimbursementProposalWithTransaction(String name,
String link,
Coin requestedBsq)
throws ValidationException, InsufficientMoneyException, TxException {
throws ProposalValidationException, InsufficientMoneyException, TxException {
return reimbursementProposalFactory.createProposalWithTransaction(name,
link,
requestedBsq);
Expand All @@ -247,7 +252,7 @@ public ProposalWithTransaction getParamProposalWithTransaction(String name,
String link,
Param param,
String paramValue)
throws ValidationException, InsufficientMoneyException, TxException {
throws ProposalValidationException, InsufficientMoneyException, TxException {
return changeParamProposalFactory.createProposalWithTransaction(name,
link,
param,
Expand All @@ -257,27 +262,27 @@ public ProposalWithTransaction getParamProposalWithTransaction(String name,
public ProposalWithTransaction getConfiscateBondProposalWithTransaction(String name,
String link,
String lockupTxId)
throws ValidationException, InsufficientMoneyException, TxException {
throws ProposalValidationException, InsufficientMoneyException, TxException {
return confiscateBondProposalFactory.createProposalWithTransaction(name,
link,
lockupTxId);
}

public ProposalWithTransaction getBondedRoleProposalWithTransaction(Role role)
throws ValidationException, InsufficientMoneyException, TxException {
throws ProposalValidationException, InsufficientMoneyException, TxException {
return roleProposalFactory.createProposalWithTransaction(role);
}

public ProposalWithTransaction getGenericProposalWithTransaction(String name,
String link)
throws ValidationException, InsufficientMoneyException, TxException {
throws ProposalValidationException, InsufficientMoneyException, TxException {
return genericProposalFactory.createProposalWithTransaction(name, link);
}

public ProposalWithTransaction getRemoveAssetProposalWithTransaction(String name,
String link,
Asset asset)
throws ValidationException, InsufficientMoneyException, TxException {
throws ProposalValidationException, InsufficientMoneyException, TxException {
return removeAssetProposalFactory.createProposalWithTransaction(name, link, asset);
}

Expand Down Expand Up @@ -362,7 +367,7 @@ public Coin getBlindVoteFeeForCycle() {
return BlindVoteConsensus.getFee(daoStateService, daoStateService.getChainHeight());
}

public Tuple2<Coin, Integer> getMiningFeeAndTxSize(Coin stake)
public Tuple2<Coin, Integer> getBlindVoteMiningFeeAndTxSize(Coin stake)
throws WalletException, InsufficientMoneyException, TransactionVerificationException {
return myBlindVoteListService.getMiningFeeAndTxSize(stake);
}
Expand Down Expand Up @@ -473,7 +478,8 @@ public int getDurationForPhaseForDisplay(DaoPhase.Phase phase) {
}

public int getCurrentCycleDuration() {
return periodService.getCurrentCycle().getDuration();
Cycle currentCycle = periodService.getCurrentCycle();
return currentCycle != null ? currentCycle.getDuration() : 0;
}

// listeners for phase change
Expand Down Expand Up @@ -548,10 +554,6 @@ public Optional<Tx> getTx(String txId) {
return daoStateService.getTx(txId);
}

public Set<TxOutput> getUnspentBlindVoteStakeTxOutputs() {
return daoStateService.getUnspentBlindVoteStakeTxOutputs();
}

public int getGenesisBlockHeight() {
return daoStateService.getGenesisBlockHeight();
}
Expand Down Expand Up @@ -584,10 +586,6 @@ public Optional<TxOutput> getLockupTxOutput(String txId) {
return daoStateService.getLockupTxOutput(txId);
}

public Optional<TxOutput> getLockupOpReturnTxOutput(String txId) {
return daoStateService.getLockupOpReturnTxOutput(txId);
}

public long getTotalBurntFee() {
return daoStateService.getTotalBurntFee();
}
Expand Down Expand Up @@ -632,15 +630,6 @@ public boolean isTxInCorrectCycle(String txId, int chainHeight) {
return periodService.isTxInCorrectCycle(txId, chainHeight);
}

public boolean isTxInPhaseAndCycle(String txId, DaoPhase.Phase phase, int chainHeight) {
return periodService.isTxInPhaseAndCycle(txId, phase, chainHeight);
}

public boolean isUnspent(TxOutputKey key) {
return daoStateService.isUnspent(key);
}


public Coin getMinCompensationRequestAmount() {
return CompensationConsensus.getMinCompensationRequestAmount(daoStateService, periodService.getChainHeight());
}
Expand Down Expand Up @@ -672,4 +661,35 @@ public boolean isMyRole(Role role) {
public Optional<Bond> getBondByLockupTxId(String lockupTxId) {
return getAllBonds().stream().filter(e -> lockupTxId.equals(e.getLockupTxId())).findAny();
}

public double getRequiredThreshold(Proposal proposal) {
return proposalService.getRequiredThreshold(proposal);
}

public Coin getRequiredQuorum(Proposal proposal) {
return proposalService.getRequiredQuorum(proposal);
}

public long getRequiredBond(Optional<RoleProposal> roleProposal) {
ManfredKarrer marked this conversation as resolved.
Show resolved Hide resolved
Optional<BondedRoleType> bondedRoleType = roleProposal.map(e -> e.getRole().getBondedRoleType());
checkArgument(bondedRoleType.isPresent(), "bondedRoleType must be present");
int height = roleProposal.flatMap(p -> daoStateService.getTx(p.getTxId()))
.map(BaseTx::getBlockHeight)
.orElse(daoStateService.getChainHeight());
long requiredBondUnit = roleProposal.map(RoleProposal::getRequiredBondUnit)
.orElse(bondedRoleType.get().getRequiredBondUnit());
long baseFactor = daoStateService.getParamValueAsCoin(Param.BONDED_ROLE_FACTOR, height).value;
return requiredBondUnit * baseFactor;
}

public long getRequiredBond(RoleProposal roleProposal) {
return getRequiredBond(Optional.of(roleProposal));
}

public long getRequiredBond(BondedRoleType bondedRoleType) {
int height = daoStateService.getChainHeight();
long requiredBondUnit = bondedRoleType.getRequiredBondUnit();
long baseFactor = daoStateService.getParamValueAsCoin(Param.BONDED_ROLE_FACTOR, height).value;
return requiredBondUnit * baseFactor;
}
}
6 changes: 3 additions & 3 deletions core/src/main/java/bisq/core/dao/DaoModule.java
Expand Up @@ -41,7 +41,7 @@
import bisq.core.dao.governance.proposal.MyProposalListService;
import bisq.core.dao.governance.proposal.ProposalListPresentation;
import bisq.core.dao.governance.proposal.ProposalService;
import bisq.core.dao.governance.proposal.ProposalValidator;
import bisq.core.dao.governance.proposal.ProposalValidatorProvider;
import bisq.core.dao.governance.proposal.compensation.CompensationProposalFactory;
import bisq.core.dao.governance.proposal.compensation.CompensationValidator;
import bisq.core.dao.governance.proposal.confiscatebond.ConfiscateBondProposalFactory;
Expand Down Expand Up @@ -150,7 +150,8 @@ protected void configure() {
bind(ProposalStorageService.class).in(Singleton.class);
bind(TempProposalStore.class).in(Singleton.class);
bind(TempProposalStorageService.class).in(Singleton.class);
bind(ProposalValidator.class).in(Singleton.class);

bind(ProposalValidatorProvider.class).in(Singleton.class);

bind(CompensationValidator.class).in(Singleton.class);
bind(CompensationProposalFactory.class).in(Singleton.class);
Expand All @@ -173,7 +174,6 @@ protected void configure() {
bind(RemoveAssetValidator.class).in(Singleton.class);
bind(RemoveAssetProposalFactory.class).in(Singleton.class);


// Ballot
bind(BallotListService.class).in(Singleton.class);
bind(BallotListPresentation.class).in(Singleton.class);
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/bisq/core/dao/DaoSetupService.java
Expand Up @@ -18,7 +18,7 @@
package bisq.core.dao;

/**
* All main service classes implements that interface to guaranteee a controlled
* All main service classes implements that interface to guarantee a controlled
* startup sequence.
*/
public interface DaoSetupService {
Expand Down