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

Add hash of dao state #2532

Merged
merged 33 commits into from
Mar 16, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
0d0713b
Remove optional setting of pubKeyScript
ManfredKarrer Mar 8, 2019
22c0388
Add comment
ManfredKarrer Mar 8, 2019
2a4270d
Merge branch 'master' into add-hash-of-dao-state
ManfredKarrer Mar 8, 2019
40b6505
Add monitoring for hash of DaoState
ManfredKarrer Mar 9, 2019
51ec876
Add removeLinebreaks parameter to toTruncatedString
ManfredKarrer Mar 9, 2019
fcd7997
Create chain of dao state hashes for monitoring consensus issues
ManfredKarrer Mar 11, 2019
d09e770
Add parseBlockchainComplete check
ManfredKarrer Mar 11, 2019
e7bfba0
Add comment
ManfredKarrer Mar 11, 2019
bbec682
Add UI for Dao state monitor
ManfredKarrer Mar 11, 2019
f560413
Update UI, remove checkArgument call
ManfredKarrer Mar 12, 2019
dbb0ba3
Add check for address
ManfredKarrer Mar 12, 2019
c280f30
Use domain data or sorting
ManfredKarrer Mar 13, 2019
47024d1
Show dash instead of N/A for prev hash at genesis height
ManfredKarrer Mar 13, 2019
d235e9c
Avoid logging at startup
ManfredKarrer Mar 13, 2019
eb3d65d
Add snapshot support for hashChain
ManfredKarrer Mar 14, 2019
9c01560
Call listeners only after batch of hashes is processed
ManfredKarrer Mar 14, 2019
2009c30
Refactor dao state monitor
ManfredKarrer Mar 15, 2019
3685270
Move monitor view to new tab
ManfredKarrer Mar 15, 2019
59bed76
Add proposal monitor view
ManfredKarrer Mar 15, 2019
3411cde
Reflect code review comments
ManfredKarrer Mar 15, 2019
52e1455
Refactor updateHashChain
ManfredKarrer Mar 15, 2019
2109c66
Add num proposals
ManfredKarrer Mar 15, 2019
4af7495
Add blind vote monitoring
ManfredKarrer Mar 16, 2019
933fa46
Fix table layout issue
ManfredKarrer Mar 16, 2019
ccbb578
Add peer to log
ManfredKarrer Mar 16, 2019
00e350e
Small fixes
ManfredKarrer Mar 16, 2019
e3dace8
Fix tests
ManfredKarrer Mar 16, 2019
e933584
Remove db store file
ManfredKarrer Mar 16, 2019
0b15246
Add updated db files
ManfredKarrer Mar 16, 2019
b222fd2
Change file name for DaoStateStore db file to DaoStateStore2, Cleanup
ManfredKarrer Mar 16, 2019
82e2a48
Add comments
ManfredKarrer Mar 16, 2019
0ba2f6f
Cleanup after code inspection
ManfredKarrer Mar 16, 2019
b7941c8
Merge branch 'master' into add-hash-of-dao-state
ManfredKarrer Mar 16, 2019
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
3 changes: 2 additions & 1 deletion common/src/main/java/bisq/common/app/Capability.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,6 @@ public enum Capability {
PROPOSAL,
BLIND_VOTE,
ACK_MSG,
BSQ_BLOCK
BSQ_BLOCK,
DAO_STATE
}
28 changes: 21 additions & 7 deletions common/src/main/java/bisq/common/util/Utilities.java
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ public static ScheduledThreadPoolExecutor getScheduledThreadPoolExecutor(String
public static boolean isMacMenuBarDarkMode() {
try {
// check for exit status only. Once there are more modes than "dark" and "default", we might need to analyze string contents..
final Process process = Runtime.getRuntime().exec(new String[] {"defaults", "read", "-g", "AppleInterfaceStyle"});
Process process = Runtime.getRuntime().exec(new String[]{"defaults", "read", "-g", "AppleInterfaceStyle"});
process.waitFor(100, TimeUnit.MILLISECONDS);
return process.exitValue() == 0;
} catch (IOException | InterruptedException | IllegalThreadStateException ex) {
Expand Down Expand Up @@ -512,15 +512,29 @@ public static void checkCryptoPolicySetup() throws NoSuchAlgorithmException, Lim
throw new LimitedKeyStrengthException();
}

public static String toTruncatedString(Object message) {
return toTruncatedString(message, 200, true);
}

public static String toTruncatedString(Object message, int maxLength) {
if (message != null) {
return StringUtils.abbreviate(message.toString(), maxLength).replace("\n", "");
}
return "null";
return toTruncatedString(message, maxLength, true);
}

public static String toTruncatedString(Object message) {
return toTruncatedString(message, 200);
public static String toTruncatedString(Object message, boolean removeLinebreaks) {
return toTruncatedString(message, 200, removeLinebreaks);
}

public static String toTruncatedString(Object message, int maxLength, boolean removeLinebreaks) {
if (message == null)
return "null";


String result = StringUtils.abbreviate(message.toString(), maxLength);
if (removeLinebreaks)
return result.replace("\n", "");

return result;

}

public static String getRandomPrefix(int minLength, int maxLength) {
Expand Down
73 changes: 72 additions & 1 deletion common/src/main/proto/pb.proto
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,15 @@ message NetworkEnvelope {
AddPersistableNetworkPayloadMessage add_persistable_network_payload_message = 31;
AckMessage ack_message = 32;
RepublishGovernanceDataRequest republish_governance_data_request = 33;
NewDaoStateHashMessage new_dao_state_hash_message = 34;
GetDaoStateHashesRequest get_dao_state_hashes_request = 35;
GetDaoStateHashesResponse get_dao_state_hashes_response = 36;
NewProposalStateHashMessage new_proposal_state_hash_message = 37;
GetProposalStateHashesRequest get_proposal_state_hashes_request = 38;
GetProposalStateHashesResponse get_proposal_state_hashes_response = 39;
NewBlindVoteStateHashMessage new_blind_vote_state_hash_message = 40;
GetBlindVoteStateHashesRequest get_blind_vote_state_hashes_request = 41;
GetBlindVoteStateHashesResponse get_blind_vote_state_hashes_response = 42;
}
}

Expand Down Expand Up @@ -324,6 +333,48 @@ message NewBlockBroadcastMessage {
message RepublishGovernanceDataRequest {
}

message NewDaoStateHashMessage {
DaoStateHash state_hash = 1;
}

message NewProposalStateHashMessage {
ProposalStateHash state_hash = 1;
}

message NewBlindVoteStateHashMessage {
BlindVoteStateHash state_hash = 1;
}

message GetDaoStateHashesRequest {
int32 height = 1;
int32 nonce = 2;
}

message GetProposalStateHashesRequest {
int32 height = 1;
int32 nonce = 2;
}

message GetBlindVoteStateHashesRequest {
int32 height = 1;
int32 nonce = 2;
}

message GetDaoStateHashesResponse {
repeated DaoStateHash state_hashes = 1;
int32 request_nonce = 2;
}

message GetProposalStateHashesResponse {
repeated ProposalStateHash state_hashes = 1;
int32 request_nonce = 2;
}

message GetBlindVoteStateHashesResponse {
repeated BlindVoteStateHash state_hashes = 1;
int32 request_nonce = 2;
}

///////////////////////////////////////////////////////////////////////////////////////////
// Payload
///////////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -915,7 +966,6 @@ message AdvancedCashAccountPayload {
string account_nr = 1;
}


///////////////////////////////////////////////////////////////////////////////////////////
// PersistableEnvelope
///////////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -1713,6 +1763,27 @@ message DecryptedBallotsWithMerits {

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

message DaoStateHash {
int32 height = 1;
bytes hash = 2;
bytes prev_hash = 3;
}

message ProposalStateHash {
int32 height = 1;
bytes hash = 2;
bytes prev_hash = 3;
int32 num_proposals = 4;
}

message BlindVoteStateHash {
int32 height = 1;
bytes hash = 2;
bytes prev_hash = 3;
int32 num_blind_votes = 4;
}

///////////////////////////////////////////////////////////////////////////////////////////
Expand Down
9 changes: 6 additions & 3 deletions core/src/main/java/bisq/core/btc/BitcoinModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,12 @@ public BitcoinModule(Environment environment) {
protected void configure() {
// We we have selected BTC_DAO_TESTNET we use our master regtest node, otherwise the specified host or default
// (localhost)
String regTestHost = BisqEnvironment.getBaseCurrencyNetwork().isDaoTestNet() ?
"104.248.31.39" :
environment.getProperty(BtcOptionKeys.REG_TEST_HOST, String.class, RegTestHost.DEFAULT_HOST);
String regTestHost = environment.getProperty(BtcOptionKeys.REG_TEST_HOST, String.class, "");
if (regTestHost.isEmpty()) {
regTestHost = BisqEnvironment.getBaseCurrencyNetwork().isDaoTestNet() ?
"104.248.31.39" :
RegTestHost.DEFAULT_HOST;
}

RegTestHost.HOST = regTestHost;
if (Arrays.asList("localhost", "127.0.0.1").contains(regTestHost)) {
Expand Down
69 changes: 69 additions & 0 deletions core/src/main/java/bisq/core/dao/DaoEventCoordinator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* 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;

import bisq.core.dao.monitoring.DaoStateMonitoringService;
import bisq.core.dao.state.DaoStateListener;
import bisq.core.dao.state.DaoStateService;
import bisq.core.dao.state.DaoStateSnapshotService;
import bisq.core.dao.state.model.blockchain.Block;

import javax.inject.Inject;

public class DaoEventCoordinator implements DaoSetupService, DaoStateListener {
private final DaoStateService daoStateService;
private final DaoStateSnapshotService daoStateSnapshotService;
private final DaoStateMonitoringService daoStateMonitoringService;

@Inject
public DaoEventCoordinator(DaoStateService daoStateService,
DaoStateSnapshotService daoStateSnapshotService,
DaoStateMonitoringService daoStateMonitoringService) {
this.daoStateService = daoStateService;
this.daoStateSnapshotService = daoStateSnapshotService;
this.daoStateMonitoringService = daoStateMonitoringService;
}


///////////////////////////////////////////////////////////////////////////////////////////
// DaoSetupService
///////////////////////////////////////////////////////////////////////////////////////////

@Override
public void addListeners() {
this.daoStateService.addDaoStateListener(this);
}

@Override
public void start() {
}


///////////////////////////////////////////////////////////////////////////////////////////
// DaoStateListener
///////////////////////////////////////////////////////////////////////////////////////////

// We listen onDaoStateChanged to ensure the dao state has been processed from listener clients after parsing.
// We need to listen during batch processing as well to write snapshots during that process.
@Override
public void onDaoStateChanged(Block block) {
// We need to execute first the daoStateMonitoringService
daoStateMonitoringService.createHashFromBlock(block);
daoStateSnapshotService.maybeCreateSnapshot(block);
}
}
13 changes: 13 additions & 0 deletions core/src/main/java/bisq/core/dao/DaoModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@
import bisq.core.dao.governance.voteresult.VoteResultService;
import bisq.core.dao.governance.voteresult.issuance.IssuanceService;
import bisq.core.dao.governance.votereveal.VoteRevealService;
import bisq.core.dao.monitoring.BlindVoteStateMonitoringService;
import bisq.core.dao.monitoring.DaoStateMonitoringService;
import bisq.core.dao.monitoring.ProposalStateMonitoringService;
import bisq.core.dao.monitoring.network.BlindVoteStateNetworkService;
import bisq.core.dao.monitoring.network.DaoStateNetworkService;
import bisq.core.dao.monitoring.network.ProposalStateNetworkService;
import bisq.core.dao.node.BsqNodeProvider;
import bisq.core.dao.node.explorer.ExportJsonFilesService;
import bisq.core.dao.node.full.FullNode;
Expand Down Expand Up @@ -99,6 +105,7 @@ public DaoModule(Environment environment) {
protected void configure() {
bind(DaoSetup.class).in(Singleton.class);
bind(DaoFacade.class).in(Singleton.class);
bind(DaoEventCoordinator.class).in(Singleton.class);
bind(DaoKillSwitch.class).in(Singleton.class);

// Node, parser
Expand All @@ -116,6 +123,12 @@ protected void configure() {
bind(DaoStateService.class).in(Singleton.class);
bind(DaoStateSnapshotService.class).in(Singleton.class);
bind(DaoStateStorageService.class).in(Singleton.class);
bind(DaoStateMonitoringService.class).in(Singleton.class);
bind(DaoStateNetworkService.class).in(Singleton.class);
bind(ProposalStateMonitoringService.class).in(Singleton.class);
bind(ProposalStateNetworkService.class).in(Singleton.class);
bind(BlindVoteStateMonitoringService.class).in(Singleton.class);
bind(BlindVoteStateNetworkService.class).in(Singleton.class);
bind(UnconfirmedBsqChangeOutputListService.class).in(Singleton.class);

bind(ExportJsonFilesService.class).in(Singleton.class);
Expand Down
18 changes: 17 additions & 1 deletion core/src/main/java/bisq/core/dao/DaoSetup.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@
import bisq.core.dao.governance.voteresult.MissingDataRequestService;
import bisq.core.dao.governance.voteresult.VoteResultService;
import bisq.core.dao.governance.votereveal.VoteRevealService;
import bisq.core.dao.monitoring.BlindVoteStateMonitoringService;
import bisq.core.dao.monitoring.DaoStateMonitoringService;
import bisq.core.dao.monitoring.ProposalStateMonitoringService;
import bisq.core.dao.node.BsqNode;
import bisq.core.dao.node.BsqNodeProvider;
import bisq.core.dao.node.explorer.ExportJsonFilesService;
Expand Down Expand Up @@ -69,11 +72,20 @@ public DaoSetup(BsqNodeProvider bsqNodeProvider,
ProofOfBurnService proofOfBurnService,
DaoFacade daoFacade,
ExportJsonFilesService exportJsonFilesService,
DaoKillSwitch daoKillSwitch) {
DaoKillSwitch daoKillSwitch,
DaoStateMonitoringService daoStateMonitoringService,
ProposalStateMonitoringService proposalStateMonitoringService,
BlindVoteStateMonitoringService blindVoteStateMonitoringService,
DaoEventCoordinator daoEventCoordinator) {

bsqNode = bsqNodeProvider.getBsqNode();

// We need to take care of order of execution.

// For order critical event flow we use the daoEventCoordinator to delegate the calls from anonymous listeners
// to concrete clients.
daoSetupServices.add(daoEventCoordinator);

daoSetupServices.add(daoStateService);
daoSetupServices.add(cycleService);
daoSetupServices.add(ballotListService);
Expand All @@ -92,6 +104,10 @@ public DaoSetup(BsqNodeProvider bsqNodeProvider,
daoSetupServices.add(daoFacade);
daoSetupServices.add(exportJsonFilesService);
daoSetupServices.add(daoKillSwitch);
daoSetupServices.add(daoStateMonitoringService);
daoSetupServices.add(proposalStateMonitoringService);
daoSetupServices.add(blindVoteStateMonitoringService);

daoSetupServices.add(bsqNodeProvider.getBsqNode());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ public void onParseBlockChainComplete() {

@Override
public void onAdded(PersistableNetworkPayload payload) {
onAppendOnlyDataAdded(payload);
onAppendOnlyDataAdded(payload, true);
}


Expand All @@ -120,16 +120,23 @@ public List<BlindVote> getBlindVotesInPhaseAndCycle() {
.collect(Collectors.toList());
}

public List<BlindVote> getConfirmedBlindVotes() {
return blindVotePayloads.stream()
.filter(blindVotePayload -> blindVoteValidator.areDataFieldsValidAndTxConfirmed(blindVotePayload.getBlindVote()))
.map(BlindVotePayload::getBlindVote)
.collect(Collectors.toList());
}


///////////////////////////////////////////////////////////////////////////////////////////
// Private
///////////////////////////////////////////////////////////////////////////////////////////

private void fillListFromAppendOnlyDataStore() {
p2PService.getP2PDataStorage().getAppendOnlyDataStoreMap().values().forEach(this::onAppendOnlyDataAdded);
p2PService.getP2PDataStorage().getAppendOnlyDataStoreMap().values().forEach(e -> onAppendOnlyDataAdded(e, false));
}

private void onAppendOnlyDataAdded(PersistableNetworkPayload persistableNetworkPayload) {
private void onAppendOnlyDataAdded(PersistableNetworkPayload persistableNetworkPayload, boolean doLog) {
if (persistableNetworkPayload instanceof BlindVotePayload) {
BlindVotePayload blindVotePayload = (BlindVotePayload) persistableNetworkPayload;
if (!blindVotePayloads.contains(blindVotePayload)) {
Expand All @@ -140,7 +147,9 @@ private void onAppendOnlyDataAdded(PersistableNetworkPayload persistableNetworkP
if (blindVoteValidator.areDataFieldsValid(blindVote)) {
// We don't validate as we might receive blindVotes from other cycles or phases at startup.
blindVotePayloads.add(blindVotePayload);
log.info("We received a blindVotePayload. blindVoteTxId={}", txId);
if (doLog) {
log.info("We received a blindVotePayload. blindVoteTxId={}", txId);
}
} else {
log.warn("We received an invalid blindVotePayload. blindVoteTxId={}", txId);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public class MyBlindVoteList extends PersistableList<BlindVote> implements Conse
// PROTO BUFFER
///////////////////////////////////////////////////////////////////////////////////////////

private MyBlindVoteList(List<BlindVote> list) {
public MyBlindVoteList(List<BlindVote> list) {
super(list);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ public MyBlindVoteListService(P2PService p2PService,
@Override
public void addListeners() {
daoStateService.addDaoStateListener(this);
p2PService.getNumConnectedPeers().addListener(numConnectedPeersListener);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public void start() {
public void onNewBlockHeight(int blockHeight) {
if (blockHeight != genesisBlockHeight)
maybeCreateNewCycle(blockHeight, daoStateService.getCycles())
.ifPresent(daoStateService.getCycles()::add);
.ifPresent(daoStateService::addCycle);
}


Expand All @@ -88,7 +88,7 @@ public void onNewBlockHeight(int blockHeight) {
///////////////////////////////////////////////////////////////////////////////////////////

public void addFirstCycle() {
daoStateService.getCycles().add(getFirstCycle());
daoStateService.addCycle(getFirstCycle());
}

public int getCycleIndex(Cycle cycle) {
Expand Down
Loading