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 irregular txType, add check for total balance, prevent proposal withhold attack #2587

Merged
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
c20964f
Don't create vote reveal tx in last block of phase
ManfredKarrer Mar 26, 2019
ce1da64
Add IRREGULAR txType for txs which are not rule conform but not burnt
ManfredKarrer Mar 26, 2019
ff86831
Merge branch 'master' into add-check-for-bsq-balance
ManfredKarrer Mar 26, 2019
3d5ff1c
Update core/src/main/java/bisq/core/dao/governance/votereveal/VoteRev…
sqrrm Mar 26, 2019
83b7ed9
Update core/src/main/java/bisq/core/dao/governance/votereveal/VoteRev…
sqrrm Mar 26, 2019
a3e1e67
Update core/src/main/java/bisq/core/dao/node/parser/TxParser.java
sqrrm Mar 26, 2019
2758db5
Update desktop/src/main/java/bisq/desktop/main/dao/wallet/dashboard/B…
sqrrm Mar 27, 2019
7479b88
Keep invalid state for txs which cannot have been created by the app
ManfredKarrer Mar 27, 2019
121c0f6
Merge branch 'add-check-for-bsq-balance' of https://github.com/Manfre…
ManfredKarrer Mar 27, 2019
bf83687
Rename BTC_DAO_TESTNET to BTC_DAO_TESTNET2 to enforce new network
ManfredKarrer Mar 27, 2019
8016f45
Add try/catch to print error in case the file does not exist
ManfredKarrer Mar 27, 2019
793d006
Rename BTC_DAO_TESTNET2 to BTC_DAO_REGTEST
ManfredKarrer Mar 27, 2019
1bd6f03
Add new genesis tx for DAO_REGTEST
ManfredKarrer Mar 27, 2019
999fe85
Reduce durations of phases for DAO_REGTEST
ManfredKarrer Mar 27, 2019
fa8b8c5
use new DAO_REGTEST server and seeds
ManfredKarrer Mar 27, 2019
c1edc62
Fix incorrect seed address
ManfredKarrer Mar 27, 2019
73b0a17
Add log for seeds
ManfredKarrer Mar 27, 2019
c6947ba
Merge branch 'master' into add-check-for-bsq-balance
ManfredKarrer Mar 27, 2019
8704ba9
Remove unused param
ManfredKarrer Mar 27, 2019
af3aedb
Update core/src/main/java/bisq/core/dao/governance/param/Param.java
sqrrm Mar 27, 2019
f0787d8
Update core/src/main/java/bisq/core/dao/governance/param/Param.java
sqrrm Mar 27, 2019
9202d28
Update core/src/main/java/bisq/core/dao/governance/param/Param.java
sqrrm Mar 27, 2019
499d91e
Improve formatting
ManfredKarrer Mar 28, 2019
f3ad4ea
Cleanup, add string
ManfredKarrer Mar 28, 2019
39ee4c0
Protect against proposal withhold attack
ManfredKarrer Mar 28, 2019
c3a8c27
Update core/src/main/java/bisq/core/dao/governance/voteresult/VoteRes…
sqrrm Mar 28, 2019
24811ff
Update core/src/main/java/bisq/core/dao/governance/voteresult/VoteRes…
sqrrm Mar 28, 2019
695ed13
Fix if else case
ManfredKarrer Mar 29, 2019
96a20ae
Merge branch 'add-check-for-bsq-balance' of https://github.com/Manfre…
ManfredKarrer Mar 29, 2019
18a3f1e
Merge branch 'master' into add-check-for-bsq-balance
ManfredKarrer Mar 29, 2019
acf2648
Use lockupTxId instead of uid
ManfredKarrer Mar 29, 2019
bb7ff47
Add random delay for proposalPayload publishing
ManfredKarrer Mar 29, 2019
30059eb
Cleanup
ManfredKarrer Mar 29, 2019
995844f
Remove setFitToRowsForTableView, update merit at activate
ManfredKarrer Mar 29, 2019
a08b910
Add support for displaying burned BSQ from invalid txs
ManfredKarrer Mar 30, 2019
bec73dc
Add popup in case the utxo balance does not match the bsq balance
ManfredKarrer Mar 30, 2019
4b11e58
Set MAINNET_GENESIS_TOTAL_SUPPLY of old mainnet genesis
ManfredKarrer Mar 30, 2019
d5c7e0a
Improve Merit handling
ManfredKarrer Mar 30, 2019
a28805b
Use onParseBlockCompleteAfterBatchProcessing to avoid sequence issues
ManfredKarrer Mar 30, 2019
a71a573
Add better comments, cleanup
ManfredKarrer Mar 30, 2019
1e6f0bf
Refactoring: Rename method
ManfredKarrer Mar 30, 2019
b39c8be
Refactoring: Rename method
ManfredKarrer Mar 30, 2019
e2d9fe1
Fix comment
ManfredKarrer Mar 30, 2019
69b134b
Refactoring: Rename method
ManfredKarrer Mar 30, 2019
d422a73
Handle merits better
ManfredKarrer Mar 30, 2019
823cec0
Improve handling fo p2p network data broadcasts
ManfredKarrer Mar 30, 2019
d5fc7cb
Use burnedBsq field in Tx for burnedFee and invalidatedBsq
ManfredKarrer Mar 31, 2019
fe646e5
Add string validations
ManfredKarrer Mar 31, 2019
e624625
Fix missing close handler and avoid nullPointer exception
ManfredKarrer Mar 31, 2019
122bc80
Use null instead of empty string for txId
ManfredKarrer Mar 31, 2019
73db81a
Add more validation
ManfredKarrer Mar 31, 2019
c7bd2ee
Add BTC_DAO_TESTNET again to keep supporting current dao testnet
ManfredKarrer Mar 31, 2019
fa3ec34
Merge branch 'master' into add-check-for-bsq-balance
ManfredKarrer Mar 31, 2019
431f76e
Add BTC_DAO_TESTNET
ManfredKarrer Mar 31, 2019
e74ce12
Improve comments, cleanup
ManfredKarrer Mar 31, 2019
30a710f
Cleanup
ManfredKarrer Mar 31, 2019
dad4b04
Update comment
ManfredKarrer Mar 31, 2019
4d56ce9
Apply ExtraDataMapValidator for all extraDataMap fields
ManfredKarrer Mar 31, 2019
e9e4b49
Add number of irregular txs to UI
ManfredKarrer Mar 31, 2019
0e2bb14
Break up lines
ManfredKarrer Mar 31, 2019
f95f770
Update witness file
ManfredKarrer Mar 31, 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
1 change: 1 addition & 0 deletions common/src/main/proto/pb.proto
Original file line number Diff line number Diff line change
Expand Up @@ -1440,6 +1440,7 @@ enum TxType {
UNLOCK = 13;
ASSET_LISTING_FEE = 14;
PROOF_OF_BURN = 15;
IRREGULAR = 16;
}

message TxInput {
Expand Down
11 changes: 8 additions & 3 deletions core/src/main/java/bisq/core/app/BisqEnvironment.java
Original file line number Diff line number Diff line change
Expand Up @@ -361,9 +361,14 @@ public BisqEnvironment(PropertySource commandLineProperties) {
final String bannedBtcNodesAsString = getProperty(FilterManager.BANNED_BTC_NODES, "");
bannedBtcNodes = !bannedBtcNodesAsString.isEmpty() ? Arrays.asList(StringUtils.deleteWhitespace(bannedBtcNodesAsString).split(",")) : null;

baseCurrencyNetwork = BaseCurrencyNetwork.valueOf(getProperty(BtcOptionKeys.BASE_CURRENCY_NETWORK,
getDefaultBaseCurrencyNetwork().name()).toUpperCase());

try {
// We replaced DAO_TESTNET with DAO_REGTEST. If user had DAO_TESTNET in his property file we
// get an exception and set the baseCurrencyNetwork to BTC_DAO_REGTEST
baseCurrencyNetwork = BaseCurrencyNetwork.valueOf(getProperty(BtcOptionKeys.BASE_CURRENCY_NETWORK,
getDefaultBaseCurrencyNetwork().name()).toUpperCase());
} catch (Throwable t) {
baseCurrencyNetwork = BaseCurrencyNetwork.BTC_DAO_REGTEST;
}
btcNetworkDir = Paths.get(appDataDir, baseCurrencyNetwork.name().toLowerCase()).toString();
File btcNetworkDirFile = new File(btcNetworkDir);
if (!btcNetworkDirFile.exists())
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/bisq/core/app/BisqExecutable.java
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,7 @@ protected void customizeOptionParsing(OptionParser parser) {
format("Base currency network (default: %s)", BisqEnvironment.getDefaultBaseCurrencyNetwork().name()))
.withRequiredArg()
.ofType(String.class)
.describedAs(format("%s|%s|%s|%s", BTC_MAINNET, BTC_TESTNET, BTC_REGTEST, BTC_DAO_TESTNET, BTC_DAO_BETANET));
.describedAs(format("%s|%s|%s|%s", BTC_MAINNET, BTC_TESTNET, BTC_REGTEST, BTC_DAO_REGTEST, BTC_DAO_BETANET));

parser.accepts(BtcOptionKeys.REG_TEST_HOST,
format("Bitcoin regtest host when using BTC_REGTEST network (default: %s)", RegTestHost.DEFAULT_HOST))
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/bisq/core/app/BisqSetup.java
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ private void maybeShowTac() {

private void checkIfLocalHostNodeIsRunning() {
// For DAO testnet we ignore local btc node
if (BisqEnvironment.getBaseCurrencyNetwork().isDaoTestNet()) {
if (BisqEnvironment.getBaseCurrencyNetwork().isDaoRegTest()) {
step3();
} else {
Thread checkIfLocalHostNodeIsRunningThread = new Thread(() -> {
Expand Down
6 changes: 3 additions & 3 deletions core/src/main/java/bisq/core/btc/BaseCurrencyNetwork.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public enum BaseCurrencyNetwork {
BTC_MAINNET(MainNetParams.get(), "BTC", "MAINNET", "Bitcoin"),
BTC_TESTNET(TestNet3Params.get(), "BTC", "TESTNET", "Bitcoin"),
BTC_REGTEST(RegTestParams.get(), "BTC", "REGTEST", "Bitcoin"),
BTC_DAO_TESTNET(RegTestParams.get(), "BTC", "REGTEST", "Bitcoin"), // server side regtest
BTC_DAO_REGTEST(RegTestParams.get(), "BTC", "REGTEST", "Bitcoin"), // server side regtest
BTC_DAO_BETANET(MainNetParams.get(), "BTC", "MAINNET", "Bitcoin"); // mainnet test genesis

@Getter
Expand All @@ -55,8 +55,8 @@ public boolean isTestnet() {
return "BTC_TESTNET".equals(name());
}

public boolean isDaoTestNet() {
return "BTC_DAO_TESTNET".equals(name());
public boolean isDaoRegTest() {
return "BTC_DAO_REGTEST".equals(name());
}

public boolean isDaoBetaNet() {
Expand Down
6 changes: 3 additions & 3 deletions core/src/main/java/bisq/core/btc/BitcoinModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,12 @@ public BitcoinModule(Environment environment) {

@Override
protected void configure() {
// We we have selected BTC_DAO_TESTNET we use our master regtest node, otherwise the specified host or default
// We we have selected BTC_DAO_REGTEST we use our master regtest node, otherwise the specified host or default
// (localhost)
String regTestHost = environment.getProperty(BtcOptionKeys.REG_TEST_HOST, String.class, "");
if (regTestHost.isEmpty()) {
regTestHost = BisqEnvironment.getBaseCurrencyNetwork().isDaoTestNet() ?
"104.248.31.39" :
regTestHost = BisqEnvironment.getBaseCurrencyNetwork().isDaoRegTest() ?
"134.209.242.206" :
RegTestHost.DEFAULT_HOST;
}

Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/bisq/core/btc/setup/WalletConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ private PeerGroup createPeerGroup() {

// For dao testnet (server side regtest) we prevent to connect to a localhost node to avoid confusion
// if local btc node is not synced with our dao testnet master node.
if (BisqEnvironment.getBaseCurrencyNetwork().isDaoTestNet())
if (BisqEnvironment.getBaseCurrencyNetwork().isDaoRegTest())
peerGroup.setUseLocalhostPeerWhenPossible(false);

return peerGroup;
Expand Down
6 changes: 6 additions & 0 deletions core/src/main/java/bisq/core/dao/DaoFacade.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
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.BaseTxOutput;
import bisq.core.dao.state.model.blockchain.Block;
import bisq.core.dao.state.model.blockchain.Tx;
import bisq.core.dao.state.model.blockchain.TxOutput;
Expand Down Expand Up @@ -543,6 +544,11 @@ public long getTotalAmountOfConfiscatedTxOutputs() {
return daoStateService.getTotalAmountOfConfiscatedTxOutputs();
}

public long getTotalAmountOfUnspentTxOutputs() {
// Does not consider confiscated outputs (they stay as utxo)
return daoStateService.getUnspentTxOutputMap().values().stream().mapToLong(BaseTxOutput::getValue).sum();
}

public Optional<Integer> getLockTime(String txId) {
return daoStateService.getLockTime(txId);
}
Expand Down
14 changes: 7 additions & 7 deletions core/src/main/java/bisq/core/dao/governance/param/Param.java
Original file line number Diff line number Diff line change
Expand Up @@ -142,55 +142,55 @@ public enum Param {
"4" : // regtest
BisqEnvironment.getBaseCurrencyNetwork().isDaoBetaNet() ?
"144" : // daoBetaNet; 1 day
"380", // testnet or dao testnet (server side regtest); 2.6 days
"134", // testnet or dao regtest (server side regtest); 2.6 days
ManfredKarrer marked this conversation as resolved.
Show resolved Hide resolved
ParamType.BLOCK, 2, 2),
PHASE_BREAK1(BisqEnvironment.getBaseCurrencyNetwork().isMainnet() ?
"149" : // mainnet; 1 day
BisqEnvironment.getBaseCurrencyNetwork().isRegtest() ?
"1" : // regtest
BisqEnvironment.getBaseCurrencyNetwork().isDaoBetaNet() ?
"10" : // daoBetaNet
"10", // testnet or dao testnet (server side regtest)
"10", // testnet or dao regtest (server side regtest)
ParamType.BLOCK, 2, 2),
PHASE_BLIND_VOTE(BisqEnvironment.getBaseCurrencyNetwork().isMainnet() ?
"451" : // mainnet; 3 days
BisqEnvironment.getBaseCurrencyNetwork().isRegtest() ?
"2" : // regtest
BisqEnvironment.getBaseCurrencyNetwork().isDaoBetaNet() ?
"144" : // daoBetaNet; 1 day
"300", // testnet or dao testnet (server side regtest); 2 days
"134", // testnet or dao regtest (server side regtest); 2 days
ManfredKarrer marked this conversation as resolved.
Show resolved Hide resolved
ParamType.BLOCK, 2, 2),
PHASE_BREAK2(BisqEnvironment.getBaseCurrencyNetwork().isMainnet() ?
"9" : // mainnet
BisqEnvironment.getBaseCurrencyNetwork().isRegtest() ?
"1" : // regtest
BisqEnvironment.getBaseCurrencyNetwork().isDaoBetaNet() ?
"10" : // daoBetaNet
"10", // testnet or dao testnet (server side regtest)
"10", // testnet or dao regtest (server side regtest)
ParamType.BLOCK, 2, 2),
PHASE_VOTE_REVEAL(BisqEnvironment.getBaseCurrencyNetwork().isMainnet() ?
"451" : // mainnet; 3 days
BisqEnvironment.getBaseCurrencyNetwork().isRegtest() ?
"2" : // regtest
BisqEnvironment.getBaseCurrencyNetwork().isDaoBetaNet() ?
"144" : // daoBetaNet; 1 day
"300", // testnet or dao testnet (server side regtest); 2 days
"132", // testnet or dao regtest (server side regtest); 2 days
ManfredKarrer marked this conversation as resolved.
Show resolved Hide resolved
ParamType.BLOCK, 2, 2),
PHASE_BREAK3(BisqEnvironment.getBaseCurrencyNetwork().isMainnet() ?
"9" : // mainnet
BisqEnvironment.getBaseCurrencyNetwork().isRegtest() ?
"1" : // regtest
BisqEnvironment.getBaseCurrencyNetwork().isDaoBetaNet() ?
"10" : // daoBetaNet
"10", // testnet or dao testnet (server side regtest)
"10", // testnet or dao regtest (server side regtest)
ParamType.BLOCK, 2, 2),
PHASE_RESULT(BisqEnvironment.getBaseCurrencyNetwork().isMainnet() ?
"10" : // mainnet
BisqEnvironment.getBaseCurrencyNetwork().isRegtest() ?
"2" : // regtest
BisqEnvironment.getBaseCurrencyNetwork().isDaoBetaNet() ?
"10" : // daoBetaNet
"2", // testnet or dao testnet (server side regtest)
"2", // testnet or dao regtest (server side regtest)
ParamType.BLOCK, 2, 2);

@Getter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,15 @@ public static TxOutput getConnectedBlindVoteStakeOutput(Tx voteRevealTx, DaoStat
Optional<TxOutput> optionalBlindVoteStakeOutput = daoStateService.getConnectedTxOutput(stakeTxInput);
checkArgument(optionalBlindVoteStakeOutput.isPresent(), "blindVoteStakeOutput must be present");
TxOutput blindVoteStakeOutput = optionalBlindVoteStakeOutput.get();
checkArgument(blindVoteStakeOutput.getTxOutputType() == TxOutputType.BLIND_VOTE_LOCK_STAKE_OUTPUT,
"blindVoteStakeOutput must be of type BLIND_VOTE_LOCK_STAKE_OUTPUT but is " +
blindVoteStakeOutput.getTxOutputType() + ". VoteRevealTx=" + voteRevealTx);
if (blindVoteStakeOutput.getTxOutputType() != TxOutputType.BLIND_VOTE_LOCK_STAKE_OUTPUT) {
String message = "blindVoteStakeOutput must be of type BLIND_VOTE_LOCK_STAKE_OUTPUT but is " +
blindVoteStakeOutput.getTxOutputType();
log.warn(message + ". VoteRevealTx=" + voteRevealTx);
throw new VoteResultException.ValidationException(message + ". VoteRevealTxId=" + voteRevealTx.getId());
}
return blindVoteStakeOutput;
} catch (VoteResultException.ValidationException t) {
throw t;
} catch (Throwable t) {
throw new VoteResultException.ValidationException(t);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,11 @@ private void maybeRevealVotes(int chainHeight) {
.filter(myVote -> myVote.getRevealTxId() == null) // we have not already revealed
.forEach(myVote -> {
boolean isInVoteRevealPhase = periodService.getPhaseForHeight(chainHeight) == DaoPhase.Phase.VOTE_REVEAL;
// If we would create the tx in the last block it would be confirmed in the best case in th next
// block which would be already the break and would invalidate the vote reveal.
boolean isLastBlockInPhase = chainHeight == periodService.getLastBlockOfPhase(chainHeight, DaoPhase.Phase.VOTE_REVEAL);
boolean isBlindVoteTxInCorrectPhaseAndCycle = periodService.isTxInPhaseAndCycle(myVote.getTxId(), DaoPhase.Phase.BLIND_VOTE, chainHeight);
if (isInVoteRevealPhase && isBlindVoteTxInCorrectPhaseAndCycle) {
if (isInVoteRevealPhase && !isLastBlockInPhase && isBlindVoteTxInCorrectPhaseAndCycle) {
log.info("We call revealVote at blockHeight {} for blindVoteTxId {}", chainHeight, myVote.getTxId());
// Standard case that we are in the correct phase and cycle and create the reveal tx.
revealVote(myVote, true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@
import bisq.core.dao.state.DaoStateListener;
import bisq.core.dao.state.DaoStateService;
import bisq.core.dao.state.GenesisTxInfo;
import bisq.core.dao.state.model.blockchain.BaseTxOutput;
import bisq.core.dao.state.model.blockchain.Block;
import bisq.core.dao.state.model.governance.IssuanceType;

import bisq.network.p2p.NodeAddress;
import bisq.network.p2p.network.Connection;
Expand Down Expand Up @@ -134,6 +136,22 @@ public void onParseBlockChainComplete() {
daoStateNetworkService.requestHashesFromAllConnectedSeedNodes(fromHeight);
}

@Override
public void onDaoStateChanged(Block block) {
long genesisTotalSupply = daoStateService.getGenesisTotalSupply().value;
long totalBurntFee = daoStateService.getTotalBurntFee();
long compensationIssuance = daoStateService.getTotalIssuedAmount(IssuanceType.COMPENSATION);
long reimbursementIssuance = daoStateService.getTotalIssuedAmount(IssuanceType.REIMBURSEMENT);
long totalConfiscatedAmount = daoStateService.getTotalAmountOfConfiscatedTxOutputs();
// confiscated funds are still in the utxo set
long sumUtxo = daoStateService.getUnspentTxOutputMap().values().stream().mapToLong(BaseTxOutput::getValue).sum();
long sumBsq = genesisTotalSupply + compensationIssuance + reimbursementIssuance - totalBurntFee;

if (sumBsq != sumUtxo) {
throw new RuntimeException("There is a mismatch between the UTXO set and the DAO state. Please contact the Bisq devlopers.");
}
}

///////////////////////////////////////////////////////////////////////////////////////////
// StateNetworkService.Listener
///////////////////////////////////////////////////////////////////////////////////////////
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ enum JsonTxType {
LOCKUP("Lockup"),
UNLOCK("Unlock"),
ASSET_LISTING_FEE("Asset listing fee"),
PROOF_OF_BURN("Proof of burn");
PROOF_OF_BURN("Proof of burn"),
IRREGULAR("Irregular");

@Getter
private String displayString;
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/bisq/core/dao/node/full/RpcService.java
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ public RpcService(Preferences preferences,
boolean isPortSet = rpcPort != null && !rpcPort.isEmpty();
boolean isMainnet = BisqEnvironment.getBaseCurrencyNetwork().isMainnet();
boolean isTestnet = BisqEnvironment.getBaseCurrencyNetwork().isTestnet();
boolean isDaoTestNet = BisqEnvironment.getBaseCurrencyNetwork().isDaoTestNet();
boolean isDaoTestNet = BisqEnvironment.getBaseCurrencyNetwork().isDaoRegTest();
boolean isDaoBetaNet = BisqEnvironment.getBaseCurrencyNetwork().isDaoBetaNet();
this.rpcPort = isPortSet ? rpcPort :
isMainnet || isDaoBetaNet ? "8332" :
Expand Down
Loading