Created
December 11, 2019 20:36
-
-
Save chimp1984/fd856131b1dbb57151dbecccae788fe9 to your computer and use it in GitHub Desktop.
patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Index: core/src/main/java/bisq/core/dao/state/model/DaoState.java | |
IDEA additional info: | |
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP | |
<+>UTF-8 | |
=================================================================== | |
--- core/src/main/java/bisq/core/dao/state/model/DaoState.java (date 1576079165000) | |
+++ core/src/main/java/bisq/core/dao/state/model/DaoState.java (date 1576096243000) | |
@@ -36,6 +36,8 @@ | |
import javax.inject.Inject; | |
import java.util.ArrayList; | |
+import java.util.Collection; | |
+import java.util.Collections; | |
import java.util.HashMap; | |
import java.util.LinkedList; | |
import java.util.List; | |
@@ -47,6 +49,8 @@ | |
import lombok.Getter; | |
import lombok.extern.slf4j.Slf4j; | |
+import javax.annotation.Nullable; | |
+ | |
/** | |
* Root class for mutable state of the DAO. | |
@@ -103,9 +107,8 @@ | |
private final List<DecryptedBallotsWithMerits> decryptedBallotsWithMeritsList; | |
// Transient data used only as an index - must be kept in sync with the block list | |
- @Getter | |
@JsonExclude | |
- private transient final Map<String, Tx> txMap; // key is txId | |
+ private transient final Map<String, Tx> txCache; // key is txId | |
/////////////////////////////////////////////////////////////////////////////////////////// | |
@@ -155,7 +158,7 @@ | |
this.evaluatedProposalList = evaluatedProposalList; | |
this.decryptedBallotsWithMeritsList = decryptedBallotsWithMeritsList; | |
- txMap = blocks.stream() | |
+ txCache = blocks.stream() | |
.flatMap(block -> block.getTxs().stream()) | |
.collect(Collectors.toMap(Tx::getId, Function.identity(), (x, y) -> y, HashMap::new)); | |
} | |
@@ -237,6 +240,28 @@ | |
return getBsqStateBuilderExcludingBlocks().addBlocks(getBlocks().getLast().toProtoMessage()).build().toByteArray(); | |
} | |
+ public void addToTxCache(Tx tx) { | |
+ txCache.put(tx.getId(), tx); | |
+ } | |
+ | |
+ public void setTxCache(Map<String, Tx> txCache) { | |
+ this.txCache.clear(); | |
+ this.txCache.putAll(txCache); | |
+ } | |
+ | |
+ public Map<String, Tx> getTxCache() { | |
+ return Collections.unmodifiableMap(txCache); | |
+ } | |
+ | |
+ public Collection<Tx> getTxsFromTxCache() { | |
+ return Collections.unmodifiableCollection(txCache.values()); | |
+ } | |
+ | |
+ @Nullable | |
+ public Tx getTxFromTxCache(String txId) { | |
+ return txCache.get(txId); | |
+ } | |
+ | |
@Override | |
public String toString() { | |
return "DaoState{" + | |
@@ -250,7 +275,7 @@ | |
",\n paramChangeList=" + paramChangeList + | |
",\n evaluatedProposalList=" + evaluatedProposalList + | |
",\n decryptedBallotsWithMeritsList=" + decryptedBallotsWithMeritsList + | |
- ",\n txMap=" + txMap + | |
+ ",\n txMap=" + txCache + | |
"\n}"; | |
} | |
} | |
Index: desktop/src/main/java/bisq/desktop/main/dao/economy/transactions/BSQTransactionsView.java | |
IDEA additional info: | |
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP | |
<+>UTF-8 | |
=================================================================== | |
--- desktop/src/main/java/bisq/desktop/main/dao/economy/transactions/BSQTransactionsView.java (date 1576079165000) | |
+++ desktop/src/main/java/bisq/desktop/main/dao/economy/transactions/BSQTransactionsView.java (date 1576090509000) | |
@@ -143,7 +143,7 @@ | |
/////////////////////////////////////////////////////////////////////////////////////////// | |
private void updateWithBsqBlockChainData() { | |
- allTxTextField.setText(String.valueOf(daoFacade.getTxs().size())); | |
+ allTxTextField.setText(String.valueOf(daoFacade.getNumTxs())); | |
utxoTextField.setText(String.valueOf(daoFacade.getUnspentTxOutputs().size())); | |
compensationIssuanceTxTextField.setText(String.valueOf(daoFacade.getNumIssuanceTransactions(IssuanceType.COMPENSATION))); | |
reimbursementIssuanceTxTextField.setText(String.valueOf(daoFacade.getNumIssuanceTransactions(IssuanceType.REIMBURSEMENT))); | |
Index: core/src/main/java/bisq/core/dao/node/parser/BlockParser.java | |
IDEA additional info: | |
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP | |
<+>UTF-8 | |
=================================================================== | |
--- core/src/main/java/bisq/core/dao/node/parser/BlockParser.java (date 1576079165000) | |
+++ core/src/main/java/bisq/core/dao/node/parser/BlockParser.java (date 1576094143000) | |
@@ -53,7 +53,6 @@ | |
// Constructor | |
/////////////////////////////////////////////////////////////////////////////////////////// | |
- @SuppressWarnings("WeakerAccess") | |
@Inject | |
public BlockParser(TxParser txParser, | |
DaoStateService daoStateService) { | |
Index: core/src/main/java/bisq/core/dao/state/model/blockchain/Block.java | |
IDEA additional info: | |
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP | |
<+>UTF-8 | |
=================================================================== | |
--- core/src/main/java/bisq/core/dao/state/model/blockchain/Block.java (date 1576079165000) | |
+++ core/src/main/java/bisq/core/dao/state/model/blockchain/Block.java (date 1576096243000) | |
@@ -24,11 +24,11 @@ | |
import com.google.common.collect.ImmutableList; | |
import java.util.ArrayList; | |
+import java.util.Collections; | |
import java.util.List; | |
import java.util.stream.Collectors; | |
import lombok.EqualsAndHashCode; | |
-import lombok.Value; | |
/** | |
* The Block which gets persisted in the DaoState. During parsing transactions can be | |
@@ -44,8 +44,8 @@ | |
* | |
*/ | |
@EqualsAndHashCode(callSuper = true) | |
-@Value | |
public final class Block extends BaseBlock implements PersistablePayload, ImmutableDaoStateModel { | |
+ // We do not expose txs with a Lombok getter. We cannot make it immutable as we add transactions during parsing. | |
private final List<Tx> txs; | |
public Block(int height, long time, String hash, String previousBlockHash) { | |
@@ -93,6 +93,21 @@ | |
txs); | |
} | |
+ public void addTx(Tx tx) { | |
+ txs.add(tx); | |
+ } | |
+ | |
+ // We want to guarantee that no client can modify the list. We use unmodifiableList and not ImmutableList as | |
+ // we want that clients reflect any change to the source list. Also ImmutableList is more expensive as it | |
+ // creates a copy. | |
+ public List<Tx> getTxs() { | |
+ return Collections.unmodifiableList(txs); | |
+ } | |
+ | |
+ public int getNumTxs() { | |
+ return txs.size(); | |
+ } | |
+ | |
@Override | |
public String toString() { | |
return "Block{" + | |
Index: core/src/main/java/bisq/core/dao/state/DaoStateService.java | |
IDEA additional info: | |
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP | |
<+>UTF-8 | |
=================================================================== | |
--- core/src/main/java/bisq/core/dao/state/DaoStateService.java (date 1576079165000) | |
+++ core/src/main/java/bisq/core/dao/state/DaoStateService.java (date 1576096243000) | |
@@ -42,11 +42,7 @@ | |
import javax.inject.Inject; | |
-import com.google.common.base.Preconditions; | |
- | |
import java.util.ArrayList; | |
-import java.util.Collection; | |
-import java.util.Collections; | |
import java.util.Comparator; | |
import java.util.HashSet; | |
import java.util.LinkedList; | |
@@ -119,8 +115,7 @@ | |
daoState.setChainHeight(snapshot.getChainHeight()); | |
- daoState.getTxMap().clear(); | |
- daoState.getTxMap().putAll(snapshot.getTxMap()); | |
+ daoState.setTxCache(snapshot.getTxCache()); | |
daoState.getBlocks().clear(); | |
daoState.getBlocks().addAll(snapshot.getBlocks()); | |
@@ -235,17 +230,26 @@ | |
// Third we add each successfully parsed BSQ tx to the last block | |
public void onNewTxForLastBlock(Block block, Tx tx) { | |
- // At least one block must be present else no rawTx would have been recognised as a BSQ tx. | |
- Preconditions.checkArgument(block == getLastBlock().orElseThrow()); | |
+ assertDaoStateChange(); | |
- block.getTxs().add(tx); | |
- daoState.getTxMap().put(tx.getId(), tx); | |
+ getLastBlock().ifPresent(lastBlock -> { | |
+ if (block == lastBlock) { | |
+ // We need to ensure that the txs in all blocks are in sync with the txs in our txMap (cache). | |
+ block.addTx(tx); | |
+ daoState.addToTxCache(tx); | |
+ } else { | |
+ // Not clear if this case can happen but at onNewBlockWithEmptyTxs we handle such a potential edge | |
+ // case as well, so we need to reflect that here as well. | |
+ log.warn("Block for parsing does not match last block. That might happen in edge cases at reorgs. " + | |
+ "Received block={}", block); | |
+ } | |
+ }); | |
} | |
// Fourth we get the onParseBlockComplete called after all rawTxs of blocks have been parsed | |
public void onParseBlockComplete(Block block) { | |
if (parseBlockChainComplete) | |
- log.info("Parse block completed: Block height {}, {} BSQ transactions.", block.getHeight(), block.getTxs().size()); | |
+ log.info("Parse block completed: Block height {}, {} BSQ transactions.", block.getHeight(), block.getNumTxs()); | |
// Need to be called before onParseTxsCompleteAfterBatchProcessing as we use it in | |
// VoteResult and other listeners like balances usually listen on onParseTxsCompleteAfterBatchProcessing | |
@@ -359,17 +363,12 @@ | |
// Tx | |
/////////////////////////////////////////////////////////////////////////////////////////// | |
- public Stream<Tx> getTxStream() { | |
- return getBlocks().stream() | |
- .flatMap(block -> block.getTxs().stream()); | |
- } | |
- | |
- private Stream<Tx> getUnorderedTxStream() { | |
- return getTxs().stream(); | |
+ public Stream<Tx> getUnorderedTxStream() { | |
+ return daoState.getTxsFromTxCache().stream(); | |
} | |
- public Collection<Tx> getTxs() { | |
- return Collections.unmodifiableCollection(daoState.getTxMap().values()); | |
+ public int getNumTxs() { | |
+ return daoState.getTxsFromTxCache().size(); | |
} | |
public List<Tx> getInvalidTxs() { | |
@@ -381,7 +380,7 @@ | |
} | |
public Optional<Tx> getTx(String txId) { | |
- return Optional.ofNullable(daoState.getTxMap().get(txId)); | |
+ return Optional.ofNullable(daoState.getTxFromTxCache(txId)); | |
} | |
public boolean containsTx(String txId) { | |
Index: core/src/main/java/bisq/core/dao/DaoFacade.java | |
IDEA additional info: | |
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP | |
<+>UTF-8 | |
=================================================================== | |
--- core/src/main/java/bisq/core/dao/DaoFacade.java (date 1576079165000) | |
+++ core/src/main/java/bisq/core/dao/DaoFacade.java (date 1576094143000) | |
@@ -94,7 +94,6 @@ | |
import java.io.IOException; | |
import java.util.ArrayList; | |
-import java.util.Collection; | |
import java.util.List; | |
import java.util.Optional; | |
import java.util.Set; | |
@@ -625,9 +624,8 @@ | |
return daoStateService.getUnspentTxOutputs(); | |
} | |
- // Returns a view rather than a copy of all the txs. | |
- public Collection<Tx> getTxs() { | |
- return daoStateService.getTxs(); | |
+ public int getNumTxs() { | |
+ return daoStateService.getNumTxs(); | |
} | |
public Optional<TxOutput> getLockupTxOutput(String txId) { | |
Index: core/src/main/java/bisq/core/dao/node/explorer/ExportJsonFilesService.java | |
IDEA additional info: | |
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP | |
<+>UTF-8 | |
=================================================================== | |
--- core/src/main/java/bisq/core/dao/node/explorer/ExportJsonFilesService.java (date 1576079165000) | |
+++ core/src/main/java/bisq/core/dao/node/explorer/ExportJsonFilesService.java (date 1576094143000) | |
@@ -140,7 +140,7 @@ | |
// Access to daoStateService is single threaded, we must not access daoStateService from the thread. | |
List<JsonTxOutput> allJsonTxOutputs = new ArrayList<>(); | |
- List<JsonTx> jsonTxs = daoStateService.getTxStream() | |
+ List<JsonTx> jsonTxs = daoStateService.getUnorderedTxStream() | |
.map(tx -> { | |
JsonTx jsonTx = getJsonTx(tx); | |
allJsonTxOutputs.addAll(jsonTx.getOutputs()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment