mirror of
https://github.com/bisq-network/bisq.git
synced 2025-02-23 06:55:08 +01:00
Revert "Fix parsertest"
This commit is contained in:
parent
182158af20
commit
456fd28e94
27 changed files with 232 additions and 398 deletions
|
@ -18,7 +18,7 @@ public class FunctionalReadWriteLock {
|
||||||
this(new ReentrantReadWriteLock(isFair));
|
this(new ReentrantReadWriteLock(isFair));
|
||||||
}
|
}
|
||||||
|
|
||||||
private FunctionalReadWriteLock(ReadWriteLock lock) {
|
public FunctionalReadWriteLock(ReadWriteLock lock) {
|
||||||
readLock = lock.readLock();
|
readLock = lock.readLock();
|
||||||
writeLock = lock.writeLock();
|
writeLock = lock.writeLock();
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,8 @@ package io.bisq.core.dao;
|
||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
import com.google.inject.name.Names;
|
import com.google.inject.name.Names;
|
||||||
import io.bisq.common.app.AppModule;
|
import io.bisq.common.app.AppModule;
|
||||||
import io.bisq.core.dao.blockchain.*;
|
import io.bisq.core.dao.blockchain.BsqBlockChain;
|
||||||
|
import io.bisq.core.dao.blockchain.BsqBlockChainChangeDispatcher;
|
||||||
import io.bisq.core.dao.blockchain.json.JsonBlockChainExporter;
|
import io.bisq.core.dao.blockchain.json.JsonBlockChainExporter;
|
||||||
import io.bisq.core.dao.node.BsqNodeProvider;
|
import io.bisq.core.dao.node.BsqNodeProvider;
|
||||||
import io.bisq.core.dao.node.consensus.*;
|
import io.bisq.core.dao.node.consensus.*;
|
||||||
|
@ -63,9 +64,6 @@ public class DaoModule extends AppModule {
|
||||||
bind(FullNode.class).in(Singleton.class);
|
bind(FullNode.class).in(Singleton.class);
|
||||||
bind(BsqNodeProvider.class).in(Singleton.class);
|
bind(BsqNodeProvider.class).in(Singleton.class);
|
||||||
bind(BsqBlockChain.class).in(Singleton.class);
|
bind(BsqBlockChain.class).in(Singleton.class);
|
||||||
bind(ReadModel.class).in(Singleton.class);
|
|
||||||
bind(WriteModel.class).in(Singleton.class);
|
|
||||||
bind(SnapshotManager.class).in(Singleton.class);
|
|
||||||
bind(BsqBlockChainChangeDispatcher.class).in(Singleton.class);
|
bind(BsqBlockChainChangeDispatcher.class).in(Singleton.class);
|
||||||
|
|
||||||
bind(GenesisTxVerification.class).in(Singleton.class);
|
bind(GenesisTxVerification.class).in(Singleton.class);
|
||||||
|
|
|
@ -98,8 +98,8 @@ public class BsqBlockChain implements PersistableEnvelope {
|
||||||
private Tx genesisTx;
|
private Tx genesisTx;
|
||||||
|
|
||||||
// not impl in PB yet
|
// not impl in PB yet
|
||||||
private final Set<Tuple2<Long, Integer>> compensationRequestFees;
|
private Set<Tuple2<Long, Integer>> compensationRequestFees;
|
||||||
private final Set<Tuple2<Long, Integer>> votingFees;
|
private Set<Tuple2<Long, Integer>> votingFees;
|
||||||
|
|
||||||
// transient
|
// transient
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@ -213,7 +213,7 @@ public class BsqBlockChain implements PersistableEnvelope {
|
||||||
// Public write access
|
// Public write access
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void applySnapshot() {
|
public void applySnapshot() {
|
||||||
lock.write(() -> {
|
lock.write(() -> {
|
||||||
checkNotNull(storage, "storage must not be null");
|
checkNotNull(storage, "storage must not be null");
|
||||||
BsqBlockChain snapshot = storage.initAndGetPersistedWithFileName("BsqBlockChain", 100);
|
BsqBlockChain snapshot = storage.initAndGetPersistedWithFileName("BsqBlockChain", 100);
|
||||||
|
@ -238,11 +238,11 @@ public class BsqBlockChain implements PersistableEnvelope {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void setCreateCompensationRequestFee(long fee, int blockHeight) {
|
public void setCreateCompensationRequestFee(long fee, int blockHeight) {
|
||||||
lock.write(() -> compensationRequestFees.add(new Tuple2<>(fee, blockHeight)));
|
lock.write(() -> compensationRequestFees.add(new Tuple2<>(fee, blockHeight)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void setVotingFee(long fee, int blockHeight) {
|
public void setVotingFee(long fee, int blockHeight) {
|
||||||
lock.write(() -> votingFees.add(new Tuple2<>(fee, blockHeight)));
|
lock.write(() -> votingFees.add(new Tuple2<>(fee, blockHeight)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,8 +251,7 @@ public class BsqBlockChain implements PersistableEnvelope {
|
||||||
// Package scope write access
|
// Package scope write access
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
//TODO refactor logic out
|
public void addBlock(BsqBlock block) throws BlockNotConnectingException {
|
||||||
void addBlock(BsqBlock block) throws BlockNotConnectingException {
|
|
||||||
try {
|
try {
|
||||||
lock.write2(() -> {
|
lock.write2(() -> {
|
||||||
if (!bsqBlocks.contains(block)) {
|
if (!bsqBlocks.contains(block)) {
|
||||||
|
@ -283,22 +282,22 @@ public class BsqBlockChain implements PersistableEnvelope {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void addTxToMap(Tx tx) {
|
public void addTxToMap(Tx tx) {
|
||||||
lock.write(() -> txMap.put(tx.getId(), tx));
|
lock.write(() -> txMap.put(tx.getId(), tx));
|
||||||
}
|
}
|
||||||
|
|
||||||
void addUnspentTxOutput(TxOutput txOutput) {
|
public void addUnspentTxOutput(TxOutput txOutput) {
|
||||||
lock.write(() -> {
|
lock.write(() -> {
|
||||||
checkArgument(txOutput.isVerified(), "txOutput must be verified at addUnspentTxOutput");
|
checkArgument(txOutput.isVerified(), "txOutput must be verified at addUnspentTxOutput");
|
||||||
unspentTxOutputsMap.put(txOutput.getTxIdIndexTuple(), txOutput);
|
unspentTxOutputsMap.put(txOutput.getTxIdIndexTuple(), txOutput);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeUnspentTxOutput(TxOutput txOutput) {
|
public void removeUnspentTxOutput(TxOutput txOutput) {
|
||||||
lock.write(() -> unspentTxOutputsMap.remove(txOutput.getTxIdIndexTuple()));
|
lock.write(() -> unspentTxOutputsMap.remove(txOutput.getTxIdIndexTuple()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void setGenesisTx(Tx tx) {
|
public void setGenesisTx(Tx tx) {
|
||||||
lock.write(() -> genesisTx = tx);
|
lock.write(() -> genesisTx = tx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -323,7 +322,7 @@ public class BsqBlockChain implements PersistableEnvelope {
|
||||||
return lock.read(() -> (BsqBlockChain) BsqBlockChain.fromProto(bsqBlockChain.getBsqBlockChainBuilder().build()));
|
return lock.read(() -> (BsqBlockChain) BsqBlockChain.fromProto(bsqBlockChain.getBsqBlockChainBuilder().build()));
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean containsBlock(BsqBlock bsqBlock) {
|
public boolean containsBlock(BsqBlock bsqBlock) {
|
||||||
return lock.read(() -> bsqBlocks.contains(bsqBlock));
|
return lock.read(() -> bsqBlocks.contains(bsqBlock));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,7 +364,7 @@ public class BsqBlockChain implements PersistableEnvelope {
|
||||||
return lock.read(() -> txMap);
|
return lock.read(() -> txMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<BsqBlock> getResetBlocksFrom(int fromBlockHeight) {
|
public List<BsqBlock> getResetBlocksFrom(int fromBlockHeight) {
|
||||||
return lock.read(() -> {
|
return lock.read(() -> {
|
||||||
BsqBlockChain clone = getClone();
|
BsqBlockChain clone = getClone();
|
||||||
List<BsqBlock> filtered = clone.bsqBlocks.stream()
|
List<BsqBlock> filtered = clone.bsqBlocks.stream()
|
||||||
|
@ -405,16 +404,16 @@ public class BsqBlockChain implements PersistableEnvelope {
|
||||||
// Package scope read access
|
// Package scope read access
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
Optional<TxOutput> getSpendableTxOutput(String txId, int index) {
|
public Optional<TxOutput> getSpendableTxOutput(String txId, int index) {
|
||||||
return lock.read(() -> getSpendableTxOutput(new TxIdIndexTuple(txId, index)));
|
return lock.read(() -> getSpendableTxOutput(new TxIdIndexTuple(txId, index)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<TxOutput> getSpendableTxOutput(TxIdIndexTuple txIdIndexTuple) {
|
public Optional<TxOutput> getSpendableTxOutput(TxIdIndexTuple txIdIndexTuple) {
|
||||||
return lock.read(() -> getUnspentTxOutput(txIdIndexTuple)
|
return lock.read(() -> getUnspentTxOutput(txIdIndexTuple)
|
||||||
.filter(this::isTxOutputMature));
|
.filter(this::isTxOutputMature));
|
||||||
}
|
}
|
||||||
|
|
||||||
long getCreateCompensationRequestFee(int blockHeight) {
|
public long getCreateCompensationRequestFee(int blockHeight) {
|
||||||
return lock.read(() -> {
|
return lock.read(() -> {
|
||||||
long fee = -1;
|
long fee = -1;
|
||||||
for (Tuple2<Long, Integer> feeAtHeight : compensationRequestFees) {
|
for (Tuple2<Long, Integer> feeAtHeight : compensationRequestFees) {
|
||||||
|
@ -427,12 +426,12 @@ public class BsqBlockChain implements PersistableEnvelope {
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO not impl yet
|
//TODO not impl yet
|
||||||
boolean isCompensationRequestPeriodValid(int blockHeight) {
|
public boolean isCompensationRequestPeriodValid(int blockHeight) {
|
||||||
return lock.read(() -> true);
|
return lock.read(() -> true);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
long getVotingFee(int blockHeight) {
|
public long getVotingFee(int blockHeight) {
|
||||||
return lock.read(() -> {
|
return lock.read(() -> {
|
||||||
long fee = -1;
|
long fee = -1;
|
||||||
for (Tuple2<Long, Integer> feeAtHeight : votingFees) {
|
for (Tuple2<Long, Integer> feeAtHeight : votingFees) {
|
||||||
|
@ -445,17 +444,17 @@ public class BsqBlockChain implements PersistableEnvelope {
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO not impl yet
|
//TODO not impl yet
|
||||||
boolean isVotingPeriodValid(int blockHeight) {
|
public boolean isVotingPeriodValid(int blockHeight) {
|
||||||
return lock.read(() -> true);
|
return lock.read(() -> true);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean existsCompensationRequestBtcAddress(String btcAddress) {
|
public boolean existsCompensationRequestBtcAddress(String btcAddress) {
|
||||||
return lock.read(() -> getAllTxOutputs().stream()
|
return lock.read(() -> getAllTxOutputs().stream()
|
||||||
.anyMatch(txOutput -> txOutput.isCompensationRequestBtcOutput() &&
|
.anyMatch(txOutput -> txOutput.isCompensationRequestBtcOutput() &&
|
||||||
btcAddress.equals(txOutput.getAddress())));
|
btcAddress.equals(txOutput.getAddress())));
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<TxOutput> findSponsoringBtcOutputsWithSameBtcAddress(String btcAddress) {
|
public Set<TxOutput> findSponsoringBtcOutputsWithSameBtcAddress(String btcAddress) {
|
||||||
return lock.read(() -> getAllTxOutputs().stream()
|
return lock.read(() -> getAllTxOutputs().stream()
|
||||||
.filter(txOutput -> txOutput.isSponsoringBtcOutput() &&
|
.filter(txOutput -> txOutput.isSponsoringBtcOutput() &&
|
||||||
btcAddress.equals(txOutput.getAddress()))
|
btcAddress.equals(txOutput.getAddress()))
|
||||||
|
|
|
@ -1,97 +0,0 @@
|
||||||
/*
|
|
||||||
* 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 io.bisq.core.dao.blockchain;
|
|
||||||
|
|
||||||
import io.bisq.core.dao.blockchain.vo.BsqBlock;
|
|
||||||
import io.bisq.core.dao.blockchain.vo.Tx;
|
|
||||||
import io.bisq.core.dao.blockchain.vo.TxOutput;
|
|
||||||
import io.bisq.core.dao.blockchain.vo.util.TxIdIndexTuple;
|
|
||||||
import org.bitcoinj.core.Coin;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Encapsulates read access to BsqBlockChain.
|
|
||||||
*/
|
|
||||||
public class ReadModel {
|
|
||||||
private BsqBlockChain bsqBlockChain;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public ReadModel(BsqBlockChain bsqBlockChain) {
|
|
||||||
this.bsqBlockChain = bsqBlockChain;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Optional<TxOutput> getSpendableTxOutput(TxIdIndexTuple txIdIndexTuple) {
|
|
||||||
return bsqBlockChain.getSpendableTxOutput(txIdIndexTuple);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Optional<TxOutput> getSpendableTxOutput(String txId, int index) {
|
|
||||||
return getSpendableTxOutput(new TxIdIndexTuple(txId, index));
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isCompensationRequestPeriodValid(int blockHeight) {
|
|
||||||
return bsqBlockChain.isCompensationRequestPeriodValid(blockHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getCreateCompensationRequestFee(int blockHeight) {
|
|
||||||
return bsqBlockChain.getCreateCompensationRequestFee(blockHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getChainHeadHeight() {
|
|
||||||
return bsqBlockChain.getChainHeadHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getGenesisTxId() {
|
|
||||||
return bsqBlockChain.getGenesisTxId();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getGenesisBlockHeight() {
|
|
||||||
return bsqBlockChain.getGenesisBlockHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean containsBlock(BsqBlock bsqBlock) {
|
|
||||||
return bsqBlockChain.containsBlock(bsqBlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<BsqBlock> getResetBlocksFrom(int fromBlockHeight) {
|
|
||||||
return bsqBlockChain.getResetBlocksFrom(fromBlockHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, Tx> getTxMap() {
|
|
||||||
return bsqBlockChain.getTxMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Tx getGenesisTx() {
|
|
||||||
return bsqBlockChain.getGenesisTx();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Coin getIssuedAmount() {
|
|
||||||
return bsqBlockChain.getIssuedAmount();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean containsTx(String txId) {
|
|
||||||
return bsqBlockChain.containsTx(txId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isTxOutputSpendable(String txId, int index) {
|
|
||||||
return bsqBlockChain.isTxOutputSpendable(txId, index);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
* 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 io.bisq.core.dao.blockchain;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
//TODO move snapshot related code from bsqBlockChain here
|
|
||||||
public class SnapshotManager {
|
|
||||||
|
|
||||||
private final BsqBlockChain bsqBlockChain;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public SnapshotManager(BsqBlockChain bsqBlockChain) {
|
|
||||||
this.bsqBlockChain = bsqBlockChain;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void applySnapshot() {
|
|
||||||
bsqBlockChain.applySnapshot();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,65 +0,0 @@
|
||||||
/*
|
|
||||||
* 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 io.bisq.core.dao.blockchain;
|
|
||||||
|
|
||||||
import io.bisq.core.dao.blockchain.exceptions.BlockNotConnectingException;
|
|
||||||
import io.bisq.core.dao.blockchain.vo.BsqBlock;
|
|
||||||
import io.bisq.core.dao.blockchain.vo.Tx;
|
|
||||||
import io.bisq.core.dao.blockchain.vo.TxOutput;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Encapsulates write access to BsqBlockChain.
|
|
||||||
*/
|
|
||||||
public class WriteModel {
|
|
||||||
private BsqBlockChain bsqBlockChain;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public WriteModel(BsqBlockChain bsqBlockChain) {
|
|
||||||
this.bsqBlockChain = bsqBlockChain;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeUnspentTxOutput(TxOutput spendableTxOutput) {
|
|
||||||
bsqBlockChain.removeUnspentTxOutput(spendableTxOutput);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addTxToMap(Tx tx) {
|
|
||||||
bsqBlockChain.addTxToMap(tx);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addUnspentTxOutput(TxOutput txOutput) {
|
|
||||||
bsqBlockChain.addUnspentTxOutput(txOutput);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setGenesisTx(Tx tx) {
|
|
||||||
bsqBlockChain.setGenesisTx(tx);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addBlock(BsqBlock bsqBlock) throws BlockNotConnectingException {
|
|
||||||
bsqBlockChain.addBlock(bsqBlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCreateCompensationRequestFee(long value, int genesisBlockHeight) {
|
|
||||||
bsqBlockChain.setCreateCompensationRequestFee(value, genesisBlockHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setVotingFee(long value, int genesisBlockHeight) {
|
|
||||||
bsqBlockChain.setVotingFee(value, genesisBlockHeight);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -19,10 +19,8 @@ package io.bisq.core.dao.node;
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import io.bisq.common.handlers.ErrorMessageHandler;
|
import io.bisq.common.handlers.ErrorMessageHandler;
|
||||||
|
import io.bisq.core.dao.blockchain.BsqBlockChain;
|
||||||
import io.bisq.core.dao.blockchain.BsqBlockChainListener;
|
import io.bisq.core.dao.blockchain.BsqBlockChainListener;
|
||||||
import io.bisq.core.dao.blockchain.ReadModel;
|
|
||||||
import io.bisq.core.dao.blockchain.SnapshotManager;
|
|
||||||
import io.bisq.core.dao.blockchain.WriteModel;
|
|
||||||
import io.bisq.core.provider.fee.FeeService;
|
import io.bisq.core.provider.fee.FeeService;
|
||||||
import io.bisq.network.p2p.P2PService;
|
import io.bisq.network.p2p.P2PService;
|
||||||
import io.bisq.network.p2p.P2PServiceListener;
|
import io.bisq.network.p2p.P2PServiceListener;
|
||||||
|
@ -42,13 +40,12 @@ public abstract class BsqNode {
|
||||||
|
|
||||||
@SuppressWarnings("WeakerAccess")
|
@SuppressWarnings("WeakerAccess")
|
||||||
protected final P2PService p2PService;
|
protected final P2PService p2PService;
|
||||||
protected final ReadModel readModel;
|
@SuppressWarnings("WeakerAccess")
|
||||||
|
protected final BsqBlockChain bsqBlockChain;
|
||||||
@SuppressWarnings("WeakerAccess")
|
@SuppressWarnings("WeakerAccess")
|
||||||
protected final List<BsqBlockChainListener> bsqBlockChainListeners = new ArrayList<>();
|
protected final List<BsqBlockChainListener> bsqBlockChainListeners = new ArrayList<>();
|
||||||
private final String genesisTxId;
|
private final String genesisTxId;
|
||||||
private final int genesisBlockHeight;
|
private final int genesisBlockHeight;
|
||||||
private final SnapshotManager snapshotManager;
|
|
||||||
@org.jetbrains.annotations.NotNull
|
|
||||||
@Getter
|
@Getter
|
||||||
protected boolean parseBlockchainComplete;
|
protected boolean parseBlockchainComplete;
|
||||||
@SuppressWarnings("WeakerAccess")
|
@SuppressWarnings("WeakerAccess")
|
||||||
|
@ -60,22 +57,19 @@ public abstract class BsqNode {
|
||||||
|
|
||||||
@SuppressWarnings("WeakerAccess")
|
@SuppressWarnings("WeakerAccess")
|
||||||
@Inject
|
@Inject
|
||||||
public BsqNode(WriteModel writeModel,
|
public BsqNode(P2PService p2PService,
|
||||||
ReadModel readModel,
|
BsqBlockChain bsqBlockChain,
|
||||||
SnapshotManager snapshotManager,
|
|
||||||
P2PService p2PService,
|
|
||||||
FeeService feeService) {
|
FeeService feeService) {
|
||||||
|
|
||||||
this.p2PService = p2PService;
|
this.p2PService = p2PService;
|
||||||
this.readModel = readModel;
|
this.bsqBlockChain = bsqBlockChain;
|
||||||
|
|
||||||
genesisTxId = readModel.getGenesisTxId();
|
genesisTxId = bsqBlockChain.getGenesisTxId();
|
||||||
genesisBlockHeight = readModel.getGenesisBlockHeight();
|
genesisBlockHeight = bsqBlockChain.getGenesisBlockHeight();
|
||||||
this.snapshotManager = snapshotManager;
|
|
||||||
|
|
||||||
writeModel.setCreateCompensationRequestFee(feeService.getCreateCompensationRequestFee().value,
|
bsqBlockChain.setCreateCompensationRequestFee(feeService.getCreateCompensationRequestFee().value,
|
||||||
genesisBlockHeight);
|
genesisBlockHeight);
|
||||||
writeModel.setVotingFee(feeService.getVotingTxFee().value,
|
bsqBlockChain.setVotingFee(feeService.getVotingTxFee().value,
|
||||||
genesisBlockHeight);
|
genesisBlockHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,16 +150,16 @@ public abstract class BsqNode {
|
||||||
|
|
||||||
@SuppressWarnings("WeakerAccess")
|
@SuppressWarnings("WeakerAccess")
|
||||||
protected int getStartBlockHeight() {
|
protected int getStartBlockHeight() {
|
||||||
final int startBlockHeight = Math.max(genesisBlockHeight, readModel.getChainHeadHeight() + 1);
|
final int startBlockHeight = Math.max(genesisBlockHeight, bsqBlockChain.getChainHeadHeight() + 1);
|
||||||
log.info("Start parse blocks:\n" +
|
log.info("Start parse blocks:\n" +
|
||||||
" Start block height={}\n" +
|
" Start block height={}\n" +
|
||||||
" Genesis txId={}\n" +
|
" Genesis txId={}\n" +
|
||||||
" Genesis block height={}\n" +
|
" Genesis block height={}\n" +
|
||||||
" Block height={}\n",
|
" BsqBlockChain block height={}\n",
|
||||||
startBlockHeight,
|
startBlockHeight,
|
||||||
genesisTxId,
|
genesisTxId,
|
||||||
genesisBlockHeight,
|
genesisBlockHeight,
|
||||||
readModel.getChainHeadHeight());
|
bsqBlockChain.getChainHeadHeight());
|
||||||
|
|
||||||
return startBlockHeight;
|
return startBlockHeight;
|
||||||
}
|
}
|
||||||
|
@ -188,7 +182,7 @@ public abstract class BsqNode {
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
private void applySnapshot() {
|
private void applySnapshot() {
|
||||||
snapshotManager.applySnapshot();
|
bsqBlockChain.applySnapshot();
|
||||||
bsqBlockChainListeners.forEach(BsqBlockChainListener::onBsqBlockChainChanged);
|
bsqBlockChainListeners.forEach(BsqBlockChainListener::onBsqBlockChainChanged);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
package io.bisq.core.dao.node;
|
package io.bisq.core.dao.node;
|
||||||
|
|
||||||
import io.bisq.common.app.DevEnv;
|
import io.bisq.common.app.DevEnv;
|
||||||
import io.bisq.core.dao.blockchain.WriteModel;
|
import io.bisq.core.dao.blockchain.BsqBlockChain;
|
||||||
import io.bisq.core.dao.blockchain.vo.Tx;
|
import io.bisq.core.dao.blockchain.vo.Tx;
|
||||||
import io.bisq.core.dao.blockchain.vo.TxInput;
|
import io.bisq.core.dao.blockchain.vo.TxInput;
|
||||||
import io.bisq.core.dao.node.consensus.BsqTxVerification;
|
import io.bisq.core.dao.node.consensus.BsqTxVerification;
|
||||||
|
@ -44,7 +44,7 @@ import static com.google.common.base.Preconditions.checkArgument;
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Immutable
|
@Immutable
|
||||||
public abstract class BsqParser {
|
public abstract class BsqParser {
|
||||||
protected final WriteModel writeModel;
|
protected final BsqBlockChain bsqBlockChain;
|
||||||
private final GenesisTxVerification genesisTxVerification;
|
private final GenesisTxVerification genesisTxVerification;
|
||||||
private final BsqTxVerification bsqTxVerification;
|
private final BsqTxVerification bsqTxVerification;
|
||||||
|
|
||||||
|
@ -55,10 +55,10 @@ public abstract class BsqParser {
|
||||||
|
|
||||||
@SuppressWarnings("WeakerAccess")
|
@SuppressWarnings("WeakerAccess")
|
||||||
@Inject
|
@Inject
|
||||||
public BsqParser(WriteModel writeModel,
|
public BsqParser(BsqBlockChain bsqBlockChain,
|
||||||
GenesisTxVerification genesisTxVerification,
|
GenesisTxVerification genesisTxVerification,
|
||||||
BsqTxVerification bsqTxVerification) {
|
BsqTxVerification bsqTxVerification) {
|
||||||
this.writeModel = writeModel;
|
this.bsqBlockChain = bsqBlockChain;
|
||||||
this.genesisTxVerification = genesisTxVerification;
|
this.genesisTxVerification = genesisTxVerification;
|
||||||
this.bsqTxVerification = bsqTxVerification;
|
this.bsqTxVerification = bsqTxVerification;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
package io.bisq.core.dao.node.consensus;
|
package io.bisq.core.dao.node.consensus;
|
||||||
|
|
||||||
|
import io.bisq.core.dao.blockchain.BsqBlockChain;
|
||||||
import io.bisq.core.dao.blockchain.vo.Tx;
|
import io.bisq.core.dao.blockchain.vo.Tx;
|
||||||
import io.bisq.core.dao.blockchain.vo.TxType;
|
import io.bisq.core.dao.blockchain.vo.TxType;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
@ -31,17 +32,26 @@ import javax.inject.Inject;
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class BsqTxVerification {
|
public class BsqTxVerification {
|
||||||
|
|
||||||
|
private final BsqBlockChain bsqBlockChain;
|
||||||
private final TxInputsVerification txInputsVerification;
|
private final TxInputsVerification txInputsVerification;
|
||||||
private final TxOutputsVerification txOutputsVerification;
|
private final TxOutputsVerification txOutputsVerification;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public BsqTxVerification(TxInputsVerification txInputsVerification,
|
public BsqTxVerification(BsqBlockChain bsqBlockChain,
|
||||||
|
TxInputsVerification txInputsVerification,
|
||||||
TxOutputsVerification txOutputsVerification) {
|
TxOutputsVerification txOutputsVerification) {
|
||||||
|
this.bsqBlockChain = bsqBlockChain;
|
||||||
this.txInputsVerification = txInputsVerification;
|
this.txInputsVerification = txInputsVerification;
|
||||||
this.txOutputsVerification = txOutputsVerification;
|
this.txOutputsVerification = txOutputsVerification;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isBsqTx(int blockHeight, Tx tx) {
|
public boolean isBsqTx(int blockHeight, Tx tx) {
|
||||||
|
return bsqBlockChain.<Boolean>callFunctionWithWriteLock(() -> execute(blockHeight, tx));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not thread safe wrt bsqBlockChain
|
||||||
|
// Check if any of the inputs are BSQ inputs and update BsqBlockChain state accordingly
|
||||||
|
private boolean execute(int blockHeight, Tx tx) {
|
||||||
BsqInputBalance bsqInputBalance = txInputsVerification.getBsqInputBalance(tx, blockHeight);
|
BsqInputBalance bsqInputBalance = txInputsVerification.getBsqInputBalance(tx, blockHeight);
|
||||||
|
|
||||||
final boolean bsqInputBalancePositive = bsqInputBalance.isPositive();
|
final boolean bsqInputBalancePositive = bsqInputBalance.isPositive();
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
package io.bisq.core.dao.node.consensus;
|
package io.bisq.core.dao.node.consensus;
|
||||||
|
|
||||||
import io.bisq.common.app.Version;
|
import io.bisq.common.app.Version;
|
||||||
import io.bisq.core.dao.blockchain.ReadModel;
|
import io.bisq.core.dao.blockchain.BsqBlockChain;
|
||||||
import io.bisq.core.dao.blockchain.vo.Tx;
|
import io.bisq.core.dao.blockchain.vo.Tx;
|
||||||
import io.bisq.core.dao.blockchain.vo.TxOutput;
|
import io.bisq.core.dao.blockchain.vo.TxOutput;
|
||||||
import io.bisq.core.dao.blockchain.vo.TxOutputType;
|
import io.bisq.core.dao.blockchain.vo.TxOutputType;
|
||||||
|
@ -26,30 +26,27 @@ import io.bisq.core.dao.blockchain.vo.TxType;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies if OP_RETURN data matches rules for a compensation request tx and applies state change.
|
* Verifies if OP_RETURN data matches rules for a compensation request tx and applies state change.
|
||||||
*/
|
*/
|
||||||
public class CompensationRequestVerification {
|
public class CompensationRequestVerification {
|
||||||
private final ReadModel readModel;
|
private final BsqBlockChain bsqBlockChain;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public CompensationRequestVerification(ReadModel readModel) {
|
public CompensationRequestVerification(BsqBlockChain bsqBlockChain) {
|
||||||
this.readModel = readModel;
|
this.bsqBlockChain = bsqBlockChain;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean verify(byte[] opReturnData, long bsqFee, int blockHeight, TxOutputsVerification.MutableState mutableState) {
|
public boolean verify(byte[] opReturnData, long bsqFee, int blockHeight, TxOutputsVerification.MutableState mutableState) {
|
||||||
return mutableState.getCompRequestIssuanceOutputCandidate() != null &&
|
return mutableState.getCompRequestIssuanceOutputCandidate() != null &&
|
||||||
opReturnData.length == 22 &&
|
opReturnData.length == 22 &&
|
||||||
Version.COMPENSATION_REQUEST_VERSION == opReturnData[1] &&
|
Version.COMPENSATION_REQUEST_VERSION == opReturnData[1] &&
|
||||||
bsqFee == readModel.getCreateCompensationRequestFee(blockHeight) &&
|
bsqFee == bsqBlockChain.getCreateCompensationRequestFee(blockHeight) &&
|
||||||
readModel.isCompensationRequestPeriodValid(blockHeight);
|
bsqBlockChain.isCompensationRequestPeriodValid(blockHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void applyStateChange(Tx tx, TxOutput opReturnTxOutput, TxOutputsVerification.MutableState mutableState) {
|
public void applyStateChange(Tx tx, TxOutput opReturnTxOutput, TxOutputsVerification.MutableState mutableState) {
|
||||||
opReturnTxOutput.setTxOutputType(TxOutputType.COMPENSATION_REQUEST_OP_RETURN_OUTPUT);
|
opReturnTxOutput.setTxOutputType(TxOutputType.COMPENSATION_REQUEST_OP_RETURN_OUTPUT);
|
||||||
checkArgument(mutableState.getCompRequestIssuanceOutputCandidate() != null, "mutableState.getCompRequestIssuanceOutputCandidate() must nto be null");
|
|
||||||
mutableState.getCompRequestIssuanceOutputCandidate().setTxOutputType(TxOutputType.COMPENSATION_REQUEST_ISSUANCE_CANDIDATE_OUTPUT);
|
mutableState.getCompRequestIssuanceOutputCandidate().setTxOutputType(TxOutputType.COMPENSATION_REQUEST_ISSUANCE_CANDIDATE_OUTPUT);
|
||||||
tx.setTxType(TxType.COMPENSATION_REQUEST);
|
tx.setTxType(TxType.COMPENSATION_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
package io.bisq.core.dao.node.consensus;
|
package io.bisq.core.dao.node.consensus;
|
||||||
|
|
||||||
import io.bisq.core.dao.DaoOptionKeys;
|
import io.bisq.core.dao.DaoOptionKeys;
|
||||||
import io.bisq.core.dao.blockchain.WriteModel;
|
import io.bisq.core.dao.blockchain.BsqBlockChain;
|
||||||
import io.bisq.core.dao.blockchain.vo.Tx;
|
import io.bisq.core.dao.blockchain.vo.Tx;
|
||||||
import io.bisq.core.dao.blockchain.vo.TxType;
|
import io.bisq.core.dao.blockchain.vo.TxType;
|
||||||
|
|
||||||
|
@ -30,15 +30,15 @@ import javax.inject.Named;
|
||||||
*/
|
*/
|
||||||
public class GenesisTxVerification {
|
public class GenesisTxVerification {
|
||||||
|
|
||||||
private final WriteModel writeModel;
|
private final BsqBlockChain bsqBlockChain;
|
||||||
private final String genesisTxId;
|
private final String genesisTxId;
|
||||||
private final int genesisBlockHeight;
|
private final int genesisBlockHeight;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public GenesisTxVerification(WriteModel writeModel,
|
public GenesisTxVerification(BsqBlockChain bsqBlockChain,
|
||||||
@Named(DaoOptionKeys.GENESIS_TX_ID) String genesisTxId,
|
@Named(DaoOptionKeys.GENESIS_TX_ID) String genesisTxId,
|
||||||
@Named(DaoOptionKeys.GENESIS_BLOCK_HEIGHT) int genesisBlockHeight) {
|
@Named(DaoOptionKeys.GENESIS_BLOCK_HEIGHT) int genesisBlockHeight) {
|
||||||
this.writeModel = writeModel;
|
this.bsqBlockChain = bsqBlockChain;
|
||||||
this.genesisTxId = genesisTxId;
|
this.genesisTxId = genesisTxId;
|
||||||
this.genesisBlockHeight = genesisBlockHeight;
|
this.genesisBlockHeight = genesisBlockHeight;
|
||||||
}
|
}
|
||||||
|
@ -51,11 +51,11 @@ public class GenesisTxVerification {
|
||||||
tx.getOutputs().forEach(txOutput -> {
|
tx.getOutputs().forEach(txOutput -> {
|
||||||
txOutput.setUnspent(true);
|
txOutput.setUnspent(true);
|
||||||
txOutput.setVerified(true);
|
txOutput.setVerified(true);
|
||||||
writeModel.addUnspentTxOutput(txOutput);
|
bsqBlockChain.addUnspentTxOutput(txOutput);
|
||||||
});
|
});
|
||||||
tx.setTxType(TxType.GENESIS);
|
tx.setTxType(TxType.GENESIS);
|
||||||
|
|
||||||
writeModel.setGenesisTx(tx);
|
bsqBlockChain.setGenesisTx(tx);
|
||||||
writeModel.addTxToMap(tx);
|
bsqBlockChain.addTxToMap(tx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,20 +17,42 @@
|
||||||
|
|
||||||
package io.bisq.core.dao.node.consensus;
|
package io.bisq.core.dao.node.consensus;
|
||||||
|
|
||||||
|
import io.bisq.core.dao.blockchain.BsqBlockChain;
|
||||||
|
import io.bisq.core.dao.blockchain.vo.Tx;
|
||||||
|
import io.bisq.core.dao.blockchain.vo.TxOutput;
|
||||||
|
import io.bisq.core.dao.blockchain.vo.TxType;
|
||||||
|
import io.bisq.core.dao.request.compensation.CompensationRequest;
|
||||||
|
import io.bisq.core.dao.request.compensation.CompensationRequestManager;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
//TODO outdated, ignore
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class IssuanceVerification {
|
public class IssuanceVerification {
|
||||||
/* private static final long MIN_BSQ_ISSUANCE_AMOUNT = 1000;
|
private static final long MIN_BSQ_ISSUANCE_AMOUNT = 1000;
|
||||||
private static final long MAX_BSQ_ISSUANCE_AMOUNT = 10_000_000;*/
|
private static final long MAX_BSQ_ISSUANCE_AMOUNT = 10_000_000;
|
||||||
|
|
||||||
|
private final BsqBlockChain bsqBlockChain;
|
||||||
|
private final PeriodVerification periodVerification;
|
||||||
|
private final VotingVerification votingVerification;
|
||||||
|
private final CompensationRequestManager compensationRequestManager;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public IssuanceVerification() {
|
public IssuanceVerification(BsqBlockChain bsqBlockChain,
|
||||||
|
PeriodVerification periodVerification,
|
||||||
|
VotingVerification votingVerification,
|
||||||
|
CompensationRequestManager compensationRequestManager) {
|
||||||
|
this.bsqBlockChain = bsqBlockChain;
|
||||||
|
this.periodVerification = periodVerification;
|
||||||
|
this.votingVerification = votingVerification;
|
||||||
|
this.compensationRequestManager = compensationRequestManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* public boolean maybeProcessData(Tx tx) {
|
public boolean maybeProcessData(Tx tx) {
|
||||||
List<TxOutput> outputs = tx.getOutputs();
|
List<TxOutput> outputs = tx.getOutputs();
|
||||||
if (outputs.size() >= 2) {
|
if (outputs.size() >= 2) {
|
||||||
TxOutput bsqTxOutput = outputs.get(0);
|
TxOutput bsqTxOutput = outputs.get(0);
|
||||||
|
@ -69,5 +91,5 @@ public class IssuanceVerification {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}*/
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,11 +17,20 @@
|
||||||
|
|
||||||
package io.bisq.core.dao.node.consensus;
|
package io.bisq.core.dao.node.consensus;
|
||||||
|
|
||||||
|
import io.bisq.core.dao.blockchain.BsqBlockChain;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
public class PeriodVerification {
|
public class PeriodVerification {
|
||||||
|
private final BsqBlockChain bsqBlockChain;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public PeriodVerification() {
|
public PeriodVerification(BsqBlockChain bsqBlockChain) {
|
||||||
|
this.bsqBlockChain = bsqBlockChain;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
public boolean isInSponsorPeriod(int blockHeight) {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,7 @@
|
||||||
|
|
||||||
package io.bisq.core.dao.node.consensus;
|
package io.bisq.core.dao.node.consensus;
|
||||||
|
|
||||||
import io.bisq.core.dao.blockchain.ReadModel;
|
import io.bisq.core.dao.blockchain.BsqBlockChain;
|
||||||
import io.bisq.core.dao.blockchain.WriteModel;
|
|
||||||
import io.bisq.core.dao.blockchain.vo.SpentInfo;
|
import io.bisq.core.dao.blockchain.vo.SpentInfo;
|
||||||
import io.bisq.core.dao.blockchain.vo.Tx;
|
import io.bisq.core.dao.blockchain.vo.Tx;
|
||||||
import io.bisq.core.dao.blockchain.vo.TxInput;
|
import io.bisq.core.dao.blockchain.vo.TxInput;
|
||||||
|
@ -35,25 +34,23 @@ import java.util.Optional;
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class TxInputVerification {
|
public class TxInputVerification {
|
||||||
|
|
||||||
private final WriteModel writeModel;
|
private final BsqBlockChain bsqBlockChain;
|
||||||
private final ReadModel readModel;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public TxInputVerification(WriteModel writeModel, ReadModel readModel) {
|
public TxInputVerification(BsqBlockChain bsqBlockChain) {
|
||||||
this.writeModel = writeModel;
|
this.bsqBlockChain = bsqBlockChain;
|
||||||
this.readModel = readModel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<TxOutput> getOptionalSpendableTxOutput(TxInput input) {
|
Optional<TxOutput> getOptionalSpendableTxOutput(TxInput input) {
|
||||||
// TODO check if Tuple indexes of inputs outputs are not messed up...
|
// TODO check if Tuple indexes of inputs outputs are not messed up...
|
||||||
// Get spendable BSQ output for txIdIndexTuple... (get output used as input in tx if it's spendable BSQ)
|
// Get spendable BSQ output for txIdIndexTuple... (get output used as input in tx if it's spendable BSQ)
|
||||||
return readModel.getSpendableTxOutput(input.getTxIdIndexTuple());
|
return bsqBlockChain.getSpendableTxOutput(input.getTxIdIndexTuple());
|
||||||
}
|
}
|
||||||
|
|
||||||
void applyStateChange(TxInput input, TxOutput spendableTxOutput, int blockHeight, Tx tx, int inputIndex) {
|
void applyStateChange(TxInput input, TxOutput spendableTxOutput, int blockHeight, Tx tx, int inputIndex) {
|
||||||
// The output is BSQ, set it as spent, update bsqBlockChain and add to available BSQ for this tx
|
// The output is BSQ, set it as spent, update bsqBlockChain and add to available BSQ for this tx
|
||||||
spendableTxOutput.setUnspent(false);
|
spendableTxOutput.setUnspent(false);
|
||||||
writeModel.removeUnspentTxOutput(spendableTxOutput);
|
bsqBlockChain.removeUnspentTxOutput(spendableTxOutput);
|
||||||
spendableTxOutput.setSpentInfo(new SpentInfo(blockHeight, tx.getId(), inputIndex));
|
spendableTxOutput.setSpentInfo(new SpentInfo(blockHeight, tx.getId(), inputIndex));
|
||||||
input.setConnectedTxOutput(spendableTxOutput);
|
input.setConnectedTxOutput(spendableTxOutput);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
package io.bisq.core.dao.node.consensus;
|
package io.bisq.core.dao.node.consensus;
|
||||||
|
|
||||||
import io.bisq.core.dao.blockchain.WriteModel;
|
import io.bisq.core.dao.blockchain.BsqBlockChain;
|
||||||
import io.bisq.core.dao.blockchain.vo.Tx;
|
import io.bisq.core.dao.blockchain.vo.Tx;
|
||||||
import io.bisq.core.dao.blockchain.vo.TxInput;
|
import io.bisq.core.dao.blockchain.vo.TxInput;
|
||||||
import io.bisq.core.dao.blockchain.vo.TxOutput;
|
import io.bisq.core.dao.blockchain.vo.TxOutput;
|
||||||
|
@ -32,12 +32,12 @@ import java.util.Optional;
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class TxInputsVerification {
|
public class TxInputsVerification {
|
||||||
|
|
||||||
private final WriteModel writeModel;
|
private final BsqBlockChain bsqBlockChain;
|
||||||
private final TxInputVerification txInputVerification;
|
private final TxInputVerification txInputVerification;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public TxInputsVerification(WriteModel writeModel, TxInputVerification txInputVerification) {
|
public TxInputsVerification(BsqBlockChain bsqBlockChain, TxInputVerification txInputVerification) {
|
||||||
this.writeModel = writeModel;
|
this.bsqBlockChain = bsqBlockChain;
|
||||||
this.txInputVerification = txInputVerification;
|
this.txInputVerification = txInputVerification;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,6 +55,6 @@ public class TxInputsVerification {
|
||||||
}
|
}
|
||||||
|
|
||||||
void applyStateChange(Tx tx) {
|
void applyStateChange(Tx tx) {
|
||||||
writeModel.addTxToMap(tx);
|
bsqBlockChain.addTxToMap(tx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
package io.bisq.core.dao.node.consensus;
|
package io.bisq.core.dao.node.consensus;
|
||||||
|
|
||||||
import io.bisq.core.dao.blockchain.WriteModel;
|
import io.bisq.core.dao.blockchain.BsqBlockChain;
|
||||||
import io.bisq.core.dao.blockchain.vo.Tx;
|
import io.bisq.core.dao.blockchain.vo.Tx;
|
||||||
import io.bisq.core.dao.blockchain.vo.TxOutput;
|
import io.bisq.core.dao.blockchain.vo.TxOutput;
|
||||||
import io.bisq.core.dao.blockchain.vo.TxOutputType;
|
import io.bisq.core.dao.blockchain.vo.TxOutputType;
|
||||||
|
@ -34,12 +34,13 @@ import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class TxOutputVerification {
|
public class TxOutputVerification {
|
||||||
private final WriteModel writeModel;
|
private final BsqBlockChain bsqBlockChain;
|
||||||
private final OpReturnVerification opReturnVerification;
|
private final OpReturnVerification opReturnVerification;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public TxOutputVerification(WriteModel writeModel, OpReturnVerification opReturnVerification) {
|
public TxOutputVerification(BsqBlockChain bsqBlockChain,
|
||||||
this.writeModel = writeModel;
|
OpReturnVerification opReturnVerification) {
|
||||||
|
this.bsqBlockChain = bsqBlockChain;
|
||||||
this.opReturnVerification = opReturnVerification;
|
this.opReturnVerification = opReturnVerification;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +100,7 @@ public class TxOutputVerification {
|
||||||
txOutput.setVerified(true);
|
txOutput.setVerified(true);
|
||||||
txOutput.setUnspent(true);
|
txOutput.setUnspent(true);
|
||||||
txOutput.setTxOutputType(TxOutputType.BSQ_OUTPUT);
|
txOutput.setTxOutputType(TxOutputType.BSQ_OUTPUT);
|
||||||
writeModel.addUnspentTxOutput(txOutput);
|
bsqBlockChain.addUnspentTxOutput(txOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyStateChangeForBtcOutput(TxOutput txOutput) {
|
private void applyStateChangeForBtcOutput(TxOutput txOutput) {
|
||||||
|
|
|
@ -23,7 +23,6 @@ import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -53,9 +52,7 @@ public class TxOutputsVerification {
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
static class MutableState {
|
static class MutableState {
|
||||||
@Nullable
|
|
||||||
private TxOutput compRequestIssuanceOutputCandidate;
|
private TxOutput compRequestIssuanceOutputCandidate;
|
||||||
@Nullable
|
|
||||||
private TxOutput bsqOutput;
|
private TxOutput bsqOutput;
|
||||||
|
|
||||||
MutableState() {
|
MutableState() {
|
||||||
|
|
|
@ -17,14 +17,54 @@
|
||||||
|
|
||||||
package io.bisq.core.dao.node.consensus;
|
package io.bisq.core.dao.node.consensus;
|
||||||
|
|
||||||
|
import io.bisq.common.app.Version;
|
||||||
|
import io.bisq.core.dao.blockchain.BsqBlockChain;
|
||||||
|
import io.bisq.core.dao.blockchain.vo.Tx;
|
||||||
|
import io.bisq.core.dao.blockchain.vo.TxOutput;
|
||||||
|
import io.bisq.core.dao.blockchain.vo.TxOutputType;
|
||||||
|
import io.bisq.core.dao.blockchain.vo.TxType;
|
||||||
|
import io.bisq.core.dao.request.compensation.CompensationRequest;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
//TODO outdated, ignore
|
||||||
|
@SuppressWarnings("unused")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class VotingVerification {
|
public class VotingVerification {
|
||||||
|
private final BsqBlockChain bsqBlockChain;
|
||||||
|
private final PeriodVerification periodVerification;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public VotingVerification() {
|
public VotingVerification(BsqBlockChain bsqBlockChain,
|
||||||
|
PeriodVerification periodVerification) {
|
||||||
|
this.bsqBlockChain = bsqBlockChain;
|
||||||
|
this.periodVerification = periodVerification;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCompensationRequestAccepted(CompensationRequest compensationRequest) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isConversionRateValid(int blockHeight, long btcAmount, long bsqAmount) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isOpReturn(Tx tx, byte[] opReturnData, TxOutput txOutput, long bsqFee, int blockHeight, TxOutput bsqOutput) {
|
||||||
|
if (Version.VOTING_VERSION == opReturnData[1] && opReturnData.length > 22) {
|
||||||
|
final int sizeOfCompRequestsVotes = (int) opReturnData[22];
|
||||||
|
if (bsqOutput != null &&
|
||||||
|
sizeOfCompRequestsVotes % 2 == 0 &&
|
||||||
|
opReturnData.length % 2 == 1 &&
|
||||||
|
opReturnData.length >= 23 + sizeOfCompRequestsVotes * 2 &&
|
||||||
|
bsqFee == bsqBlockChain.getVotingFee(blockHeight) &&
|
||||||
|
bsqBlockChain.isVotingPeriodValid(blockHeight)) {
|
||||||
|
txOutput.setTxOutputType(TxOutputType.VOTE_OP_RETURN_OUTPUT);
|
||||||
|
tx.setTxType(TxType.VOTE);
|
||||||
|
// TODO use bsqOutput as weight
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,10 +20,8 @@ package io.bisq.core.dao.node.full;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import io.bisq.common.UserThread;
|
import io.bisq.common.UserThread;
|
||||||
import io.bisq.common.handlers.ErrorMessageHandler;
|
import io.bisq.common.handlers.ErrorMessageHandler;
|
||||||
|
import io.bisq.core.dao.blockchain.BsqBlockChain;
|
||||||
import io.bisq.core.dao.blockchain.BsqBlockChainListener;
|
import io.bisq.core.dao.blockchain.BsqBlockChainListener;
|
||||||
import io.bisq.core.dao.blockchain.ReadModel;
|
|
||||||
import io.bisq.core.dao.blockchain.SnapshotManager;
|
|
||||||
import io.bisq.core.dao.blockchain.WriteModel;
|
|
||||||
import io.bisq.core.dao.blockchain.exceptions.BlockNotConnectingException;
|
import io.bisq.core.dao.blockchain.exceptions.BlockNotConnectingException;
|
||||||
import io.bisq.core.dao.blockchain.json.JsonBlockChainExporter;
|
import io.bisq.core.dao.blockchain.json.JsonBlockChainExporter;
|
||||||
import io.bisq.core.dao.blockchain.vo.BsqBlock;
|
import io.bisq.core.dao.blockchain.vo.BsqBlock;
|
||||||
|
@ -51,18 +49,14 @@ public class FullNode extends BsqNode {
|
||||||
|
|
||||||
@SuppressWarnings("WeakerAccess")
|
@SuppressWarnings("WeakerAccess")
|
||||||
@Inject
|
@Inject
|
||||||
public FullNode(WriteModel writeModel,
|
public FullNode(P2PService p2PService,
|
||||||
ReadModel readModel,
|
|
||||||
SnapshotManager snapshotManager,
|
|
||||||
P2PService p2PService,
|
|
||||||
FullNodeExecutor bsqFullNodeExecutor,
|
FullNodeExecutor bsqFullNodeExecutor,
|
||||||
|
BsqBlockChain bsqBlockChain,
|
||||||
JsonBlockChainExporter jsonBlockChainExporter,
|
JsonBlockChainExporter jsonBlockChainExporter,
|
||||||
FeeService feeService,
|
FeeService feeService,
|
||||||
FullNodeNetworkManager fullNodeNetworkManager) {
|
FullNodeNetworkManager fullNodeNetworkManager) {
|
||||||
super(writeModel,
|
super(p2PService,
|
||||||
readModel,
|
bsqBlockChain,
|
||||||
snapshotManager,
|
|
||||||
p2PService,
|
|
||||||
feeService);
|
feeService);
|
||||||
this.bsqFullNodeExecutor = bsqFullNodeExecutor;
|
this.bsqFullNodeExecutor = bsqFullNodeExecutor;
|
||||||
this.jsonBlockChainExporter = jsonBlockChainExporter;
|
this.jsonBlockChainExporter = jsonBlockChainExporter;
|
||||||
|
|
|
@ -20,7 +20,7 @@ package io.bisq.core.dao.node.full;
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.neemre.btcdcli4j.core.domain.Block;
|
import com.neemre.btcdcli4j.core.domain.Block;
|
||||||
import io.bisq.core.dao.blockchain.WriteModel;
|
import io.bisq.core.dao.blockchain.BsqBlockChain;
|
||||||
import io.bisq.core.dao.blockchain.exceptions.BlockNotConnectingException;
|
import io.bisq.core.dao.blockchain.exceptions.BlockNotConnectingException;
|
||||||
import io.bisq.core.dao.blockchain.exceptions.BsqBlockchainException;
|
import io.bisq.core.dao.blockchain.exceptions.BsqBlockchainException;
|
||||||
import io.bisq.core.dao.blockchain.vo.BsqBlock;
|
import io.bisq.core.dao.blockchain.vo.BsqBlock;
|
||||||
|
@ -57,10 +57,10 @@ public class FullNodeParser extends BsqParser {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public FullNodeParser(RpcService rpcService,
|
public FullNodeParser(RpcService rpcService,
|
||||||
WriteModel writeModel,
|
BsqBlockChain bsqBlockChain,
|
||||||
GenesisTxVerification genesisTxVerification,
|
GenesisTxVerification genesisTxVerification,
|
||||||
BsqTxVerification bsqTxVerification) {
|
BsqTxVerification bsqTxVerification) {
|
||||||
super(writeModel, genesisTxVerification, bsqTxVerification);
|
super(bsqBlockChain, genesisTxVerification, bsqTxVerification);
|
||||||
this.rpcService = rpcService;
|
this.rpcService = rpcService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ public class FullNodeParser extends BsqParser {
|
||||||
btcdBlock.getHash(),
|
btcdBlock.getHash(),
|
||||||
btcdBlock.getPreviousBlockHash(),
|
btcdBlock.getPreviousBlockHash(),
|
||||||
ImmutableList.copyOf(bsqTxsInBlock));
|
ImmutableList.copyOf(bsqTxsInBlock));
|
||||||
writeModel.addBlock(bsqBlock);
|
bsqBlockChain.addBlock(bsqBlock);
|
||||||
log.info("parseBlock took {} ms at blockHeight {}; bsqTxsInBlock.size={}",
|
log.info("parseBlock took {} ms at blockHeight {}; bsqTxsInBlock.size={}",
|
||||||
System.currentTimeMillis() - startTs, bsqBlock.getHeight(), bsqTxsInBlock.size());
|
System.currentTimeMillis() - startTs, bsqBlock.getHeight(), bsqTxsInBlock.size());
|
||||||
return bsqBlock;
|
return bsqBlock;
|
||||||
|
|
|
@ -3,7 +3,7 @@ package io.bisq.core.dao.node.full.network;
|
||||||
import io.bisq.common.UserThread;
|
import io.bisq.common.UserThread;
|
||||||
import io.bisq.common.app.Log;
|
import io.bisq.common.app.Log;
|
||||||
import io.bisq.common.proto.network.NetworkEnvelope;
|
import io.bisq.common.proto.network.NetworkEnvelope;
|
||||||
import io.bisq.core.dao.blockchain.ReadModel;
|
import io.bisq.core.dao.blockchain.BsqBlockChain;
|
||||||
import io.bisq.core.dao.blockchain.vo.BsqBlock;
|
import io.bisq.core.dao.blockchain.vo.BsqBlock;
|
||||||
import io.bisq.core.dao.node.messages.GetBsqBlocksRequest;
|
import io.bisq.core.dao.node.messages.GetBsqBlocksRequest;
|
||||||
import io.bisq.core.dao.node.messages.NewBsqBlockBroadcastMessage;
|
import io.bisq.core.dao.node.messages.NewBsqBlockBroadcastMessage;
|
||||||
|
@ -35,7 +35,7 @@ public class FullNodeNetworkManager implements MessageListener, PeerManager.List
|
||||||
private final NetworkNode networkNode;
|
private final NetworkNode networkNode;
|
||||||
private final PeerManager peerManager;
|
private final PeerManager peerManager;
|
||||||
private final Broadcaster broadcaster;
|
private final Broadcaster broadcaster;
|
||||||
private final ReadModel readModel;
|
private final BsqBlockChain bsqBlockChain;
|
||||||
|
|
||||||
// Key is connection UID
|
// Key is connection UID
|
||||||
private final Map<String, GetBsqBlocksRequestHandler> getBlocksRequestHandlers = new HashMap<>();
|
private final Map<String, GetBsqBlocksRequestHandler> getBlocksRequestHandlers = new HashMap<>();
|
||||||
|
@ -50,11 +50,11 @@ public class FullNodeNetworkManager implements MessageListener, PeerManager.List
|
||||||
public FullNodeNetworkManager(NetworkNode networkNode,
|
public FullNodeNetworkManager(NetworkNode networkNode,
|
||||||
PeerManager peerManager,
|
PeerManager peerManager,
|
||||||
Broadcaster broadcaster,
|
Broadcaster broadcaster,
|
||||||
ReadModel readModel) {
|
BsqBlockChain bsqBlockChain) {
|
||||||
this.networkNode = networkNode;
|
this.networkNode = networkNode;
|
||||||
this.peerManager = peerManager;
|
this.peerManager = peerManager;
|
||||||
this.broadcaster = broadcaster;
|
this.broadcaster = broadcaster;
|
||||||
this.readModel = readModel;
|
this.bsqBlockChain = bsqBlockChain;
|
||||||
// seedNodeAddresses can be empty (in case there is only 1 seed node, the seed node starting up has no other seed nodes)
|
// seedNodeAddresses can be empty (in case there is only 1 seed node, the seed node starting up has no other seed nodes)
|
||||||
|
|
||||||
networkNode.addMessageListener(this);
|
networkNode.addMessageListener(this);
|
||||||
|
@ -113,7 +113,7 @@ public class FullNodeNetworkManager implements MessageListener, PeerManager.List
|
||||||
final String uid = connection.getUid();
|
final String uid = connection.getUid();
|
||||||
if (!getBlocksRequestHandlers.containsKey(uid)) {
|
if (!getBlocksRequestHandlers.containsKey(uid)) {
|
||||||
GetBsqBlocksRequestHandler requestHandler = new GetBsqBlocksRequestHandler(networkNode,
|
GetBsqBlocksRequestHandler requestHandler = new GetBsqBlocksRequestHandler(networkNode,
|
||||||
readModel,
|
bsqBlockChain,
|
||||||
new GetBsqBlocksRequestHandler.Listener() {
|
new GetBsqBlocksRequestHandler.Listener() {
|
||||||
@Override
|
@Override
|
||||||
public void onComplete() {
|
public void onComplete() {
|
||||||
|
|
|
@ -6,7 +6,7 @@ import com.google.common.util.concurrent.SettableFuture;
|
||||||
import io.bisq.common.Timer;
|
import io.bisq.common.Timer;
|
||||||
import io.bisq.common.UserThread;
|
import io.bisq.common.UserThread;
|
||||||
import io.bisq.common.app.Log;
|
import io.bisq.common.app.Log;
|
||||||
import io.bisq.core.dao.blockchain.ReadModel;
|
import io.bisq.core.dao.blockchain.BsqBlockChain;
|
||||||
import io.bisq.core.dao.blockchain.vo.BsqBlock;
|
import io.bisq.core.dao.blockchain.vo.BsqBlock;
|
||||||
import io.bisq.core.dao.node.messages.GetBsqBlocksRequest;
|
import io.bisq.core.dao.node.messages.GetBsqBlocksRequest;
|
||||||
import io.bisq.core.dao.node.messages.GetBsqBlocksResponse;
|
import io.bisq.core.dao.node.messages.GetBsqBlocksResponse;
|
||||||
|
@ -43,19 +43,19 @@ class GetBsqBlocksRequestHandler {
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
private final NetworkNode networkNode;
|
private final NetworkNode networkNode;
|
||||||
private final ReadModel readModel;
|
|
||||||
private final Listener listener;
|
private final Listener listener;
|
||||||
private Timer timeoutTimer;
|
private Timer timeoutTimer;
|
||||||
private boolean stopped;
|
private boolean stopped;
|
||||||
|
private final BsqBlockChain bsqBlockChain;
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Constructor
|
// Constructor
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
public GetBsqBlocksRequestHandler(NetworkNode networkNode, ReadModel readModel, Listener listener) {
|
public GetBsqBlocksRequestHandler(NetworkNode networkNode, BsqBlockChain bsqBlockChain, Listener listener) {
|
||||||
this.networkNode = networkNode;
|
this.networkNode = networkNode;
|
||||||
this.readModel = readModel;
|
this.bsqBlockChain = bsqBlockChain;
|
||||||
this.listener = listener;
|
this.listener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ class GetBsqBlocksRequestHandler {
|
||||||
|
|
||||||
public void onGetBsqBlocksRequest(GetBsqBlocksRequest getBsqBlocksRequest, final Connection connection) {
|
public void onGetBsqBlocksRequest(GetBsqBlocksRequest getBsqBlocksRequest, final Connection connection) {
|
||||||
Log.traceCall(getBsqBlocksRequest + "\n\tconnection=" + connection);
|
Log.traceCall(getBsqBlocksRequest + "\n\tconnection=" + connection);
|
||||||
List<BsqBlock> bsqBlocks = readModel.getResetBlocksFrom(getBsqBlocksRequest.getFromBlockHeight());
|
List<BsqBlock> bsqBlocks = bsqBlockChain.getResetBlocksFrom(getBsqBlocksRequest.getFromBlockHeight());
|
||||||
final GetBsqBlocksResponse bsqBlocksResponse = new GetBsqBlocksResponse(bsqBlocks, getBsqBlocksRequest.getNonce());
|
final GetBsqBlocksResponse bsqBlocksResponse = new GetBsqBlocksResponse(bsqBlocks, getBsqBlocksRequest.getNonce());
|
||||||
log.debug("bsqBlocksResponse " + bsqBlocksResponse.getRequestNonce());
|
log.debug("bsqBlocksResponse " + bsqBlocksResponse.getRequestNonce());
|
||||||
|
|
||||||
|
|
|
@ -20,10 +20,8 @@ package io.bisq.core.dao.node.lite;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import io.bisq.common.UserThread;
|
import io.bisq.common.UserThread;
|
||||||
import io.bisq.common.handlers.ErrorMessageHandler;
|
import io.bisq.common.handlers.ErrorMessageHandler;
|
||||||
|
import io.bisq.core.dao.blockchain.BsqBlockChain;
|
||||||
import io.bisq.core.dao.blockchain.BsqBlockChainListener;
|
import io.bisq.core.dao.blockchain.BsqBlockChainListener;
|
||||||
import io.bisq.core.dao.blockchain.ReadModel;
|
|
||||||
import io.bisq.core.dao.blockchain.SnapshotManager;
|
|
||||||
import io.bisq.core.dao.blockchain.WriteModel;
|
|
||||||
import io.bisq.core.dao.blockchain.exceptions.BlockNotConnectingException;
|
import io.bisq.core.dao.blockchain.exceptions.BlockNotConnectingException;
|
||||||
import io.bisq.core.dao.blockchain.vo.BsqBlock;
|
import io.bisq.core.dao.blockchain.vo.BsqBlock;
|
||||||
import io.bisq.core.dao.node.BsqNode;
|
import io.bisq.core.dao.node.BsqNode;
|
||||||
|
@ -43,7 +41,7 @@ import java.util.function.Consumer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main class for lite nodes which receive the BSQ transactions from a full node (e.g. seed nodes).
|
* Main class for lite nodes which receive the BSQ transactions from a full node (e.g. seed nodes).
|
||||||
* <p>
|
*
|
||||||
* Verification of BSQ transactions is done also by the lite node.
|
* Verification of BSQ transactions is done also by the lite node.
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@ -58,17 +56,13 @@ public class LiteNode extends BsqNode {
|
||||||
|
|
||||||
@SuppressWarnings("WeakerAccess")
|
@SuppressWarnings("WeakerAccess")
|
||||||
@Inject
|
@Inject
|
||||||
public LiteNode(WriteModel writeModel,
|
public LiteNode(P2PService p2PService,
|
||||||
ReadModel readModel,
|
|
||||||
SnapshotManager snapshotManager,
|
|
||||||
P2PService p2PService,
|
|
||||||
LiteNodeExecutor bsqLiteNodeExecutor,
|
LiteNodeExecutor bsqLiteNodeExecutor,
|
||||||
|
BsqBlockChain bsqBlockChain,
|
||||||
FeeService feeService,
|
FeeService feeService,
|
||||||
LiteNodeNetworkManager liteNodeNetworkManager) {
|
LiteNodeNetworkManager liteNodeNetworkManager) {
|
||||||
super(writeModel,
|
super(p2PService,
|
||||||
readModel,
|
bsqBlockChain,
|
||||||
snapshotManager,
|
|
||||||
p2PService,
|
|
||||||
feeService);
|
feeService);
|
||||||
this.bsqLiteNodeExecutor = bsqLiteNodeExecutor;
|
this.bsqLiteNodeExecutor = bsqLiteNodeExecutor;
|
||||||
this.liteNodeNetworkManager = liteNodeNetworkManager;
|
this.liteNodeNetworkManager = liteNodeNetworkManager;
|
||||||
|
@ -150,7 +144,7 @@ public class LiteNode extends BsqNode {
|
||||||
// We reset all mutable data in case the provider would not have done it.
|
// We reset all mutable data in case the provider would not have done it.
|
||||||
bsqBlock.reset();
|
bsqBlock.reset();
|
||||||
log.info("onNewBlockReceived: bsqBlock={}", bsqBlock.getHeight());
|
log.info("onNewBlockReceived: bsqBlock={}", bsqBlock.getHeight());
|
||||||
if (!readModel.containsBlock(bsqBlock)) {
|
if (!bsqBlockChain.containsBlock(bsqBlock)) {
|
||||||
bsqLiteNodeExecutor.parseBlock(bsqBlock,
|
bsqLiteNodeExecutor.parseBlock(bsqBlock,
|
||||||
this::notifyListenersOnNewBlock,
|
this::notifyListenersOnNewBlock,
|
||||||
getErrorHandler());
|
getErrorHandler());
|
||||||
|
|
|
@ -24,6 +24,7 @@ import com.google.common.util.concurrent.ListeningExecutorService;
|
||||||
import io.bisq.common.UserThread;
|
import io.bisq.common.UserThread;
|
||||||
import io.bisq.common.handlers.ResultHandler;
|
import io.bisq.common.handlers.ResultHandler;
|
||||||
import io.bisq.common.util.Utilities;
|
import io.bisq.common.util.Utilities;
|
||||||
|
import io.bisq.core.dao.blockchain.BsqBlockChain;
|
||||||
import io.bisq.core.dao.blockchain.vo.BsqBlock;
|
import io.bisq.core.dao.blockchain.vo.BsqBlock;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
@ -39,6 +40,7 @@ import java.util.function.Consumer;
|
||||||
public class LiteNodeExecutor {
|
public class LiteNodeExecutor {
|
||||||
|
|
||||||
private final LiteNodeParser liteNodeParser;
|
private final LiteNodeParser liteNodeParser;
|
||||||
|
private final BsqBlockChain bsqBlockChain;
|
||||||
|
|
||||||
private final ListeningExecutorService parseBlocksExecutor = Utilities.getListeningExecutorService("ParseBlocks", 1, 1, 60);
|
private final ListeningExecutorService parseBlocksExecutor = Utilities.getListeningExecutorService("ParseBlocks", 1, 1, 60);
|
||||||
private final ListeningExecutorService parseBlockExecutor = Utilities.getListeningExecutorService("ParseBlock", 1, 1, 60);
|
private final ListeningExecutorService parseBlockExecutor = Utilities.getListeningExecutorService("ParseBlock", 1, 1, 60);
|
||||||
|
@ -50,8 +52,9 @@ public class LiteNodeExecutor {
|
||||||
|
|
||||||
@SuppressWarnings("WeakerAccess")
|
@SuppressWarnings("WeakerAccess")
|
||||||
@Inject
|
@Inject
|
||||||
public LiteNodeExecutor(LiteNodeParser liteNodeParser) {
|
public LiteNodeExecutor(LiteNodeParser liteNodeParser, BsqBlockChain bsqBlockChain) {
|
||||||
this.liteNodeParser = liteNodeParser;
|
this.liteNodeParser = liteNodeParser;
|
||||||
|
this.bsqBlockChain = bsqBlockChain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -91,6 +94,7 @@ public class LiteNodeExecutor {
|
||||||
long startTs = System.currentTimeMillis();
|
long startTs = System.currentTimeMillis();
|
||||||
liteNodeParser.parseBsqBlock(bsqBlock);
|
liteNodeParser.parseBsqBlock(bsqBlock);
|
||||||
log.info("parseBlocks took {} ms", System.currentTimeMillis() - startTs);
|
log.info("parseBlocks took {} ms", System.currentTimeMillis() - startTs);
|
||||||
|
bsqBlockChain.addBlock(bsqBlock);
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
package io.bisq.core.dao.node.lite;
|
package io.bisq.core.dao.node.lite;
|
||||||
|
|
||||||
import io.bisq.core.dao.blockchain.WriteModel;
|
import io.bisq.core.dao.blockchain.BsqBlockChain;
|
||||||
import io.bisq.core.dao.blockchain.exceptions.BlockNotConnectingException;
|
import io.bisq.core.dao.blockchain.exceptions.BlockNotConnectingException;
|
||||||
import io.bisq.core.dao.blockchain.vo.BsqBlock;
|
import io.bisq.core.dao.blockchain.vo.BsqBlock;
|
||||||
import io.bisq.core.dao.blockchain.vo.Tx;
|
import io.bisq.core.dao.blockchain.vo.Tx;
|
||||||
|
@ -40,10 +40,10 @@ import java.util.function.Consumer;
|
||||||
public class LiteNodeParser extends BsqParser {
|
public class LiteNodeParser extends BsqParser {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public LiteNodeParser(WriteModel writeModel,
|
public LiteNodeParser(BsqBlockChain bsqBlockChain,
|
||||||
GenesisTxVerification genesisTxVerification,
|
GenesisTxVerification genesisTxVerification,
|
||||||
BsqTxVerification bsqTxVerification) {
|
BsqTxVerification bsqTxVerification) {
|
||||||
super(writeModel, genesisTxVerification, bsqTxVerification);
|
super(bsqBlockChain, genesisTxVerification, bsqTxVerification);
|
||||||
}
|
}
|
||||||
|
|
||||||
void parseBsqBlocks(List<BsqBlock> bsqBlocks,
|
void parseBsqBlocks(List<BsqBlock> bsqBlocks,
|
||||||
|
@ -51,17 +51,17 @@ public class LiteNodeParser extends BsqParser {
|
||||||
throws BlockNotConnectingException {
|
throws BlockNotConnectingException {
|
||||||
for (BsqBlock bsqBlock : bsqBlocks) {
|
for (BsqBlock bsqBlock : bsqBlocks) {
|
||||||
parseBsqBlock(bsqBlock);
|
parseBsqBlock(bsqBlock);
|
||||||
|
bsqBlockChain.addBlock(bsqBlock);
|
||||||
newBlockHandler.accept(bsqBlock);
|
newBlockHandler.accept(bsqBlock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void parseBsqBlock(BsqBlock bsqBlock) throws BlockNotConnectingException {
|
void parseBsqBlock(BsqBlock bsqBlock) {
|
||||||
int blockHeight = bsqBlock.getHeight();
|
int blockHeight = bsqBlock.getHeight();
|
||||||
log.info("Parse block at height={} ", blockHeight);
|
log.info("Parse block at height={} ", blockHeight);
|
||||||
List<Tx> txList = new ArrayList<>(bsqBlock.getTxs());
|
List<Tx> txList = new ArrayList<>(bsqBlock.getTxs());
|
||||||
List<Tx> bsqTxsInBlock = new ArrayList<>();
|
List<Tx> bsqTxsInBlock = new ArrayList<>();
|
||||||
bsqBlock.getTxs().forEach(tx -> checkForGenesisTx(blockHeight, bsqTxsInBlock, tx));
|
bsqBlock.getTxs().forEach(tx -> checkForGenesisTx(blockHeight, bsqTxsInBlock, tx));
|
||||||
recursiveFindBsqTxs(bsqTxsInBlock, txList, blockHeight, 0, 5300);
|
recursiveFindBsqTxs(bsqTxsInBlock, txList, blockHeight, 0, 5300);
|
||||||
writeModel.addBlock(bsqBlock);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,9 +31,9 @@ import io.bisq.core.btc.exceptions.WalletException;
|
||||||
import io.bisq.core.btc.wallet.BsqWalletService;
|
import io.bisq.core.btc.wallet.BsqWalletService;
|
||||||
import io.bisq.core.btc.wallet.BtcWalletService;
|
import io.bisq.core.btc.wallet.BtcWalletService;
|
||||||
import io.bisq.core.dao.DaoPeriodService;
|
import io.bisq.core.dao.DaoPeriodService;
|
||||||
|
import io.bisq.core.dao.blockchain.BsqBlockChain;
|
||||||
import io.bisq.core.dao.blockchain.BsqBlockChainChangeDispatcher;
|
import io.bisq.core.dao.blockchain.BsqBlockChainChangeDispatcher;
|
||||||
import io.bisq.core.dao.blockchain.BsqBlockChainListener;
|
import io.bisq.core.dao.blockchain.BsqBlockChainListener;
|
||||||
import io.bisq.core.dao.blockchain.ReadModel;
|
|
||||||
import io.bisq.core.dao.request.compensation.consensus.OpReturnData;
|
import io.bisq.core.dao.request.compensation.consensus.OpReturnData;
|
||||||
import io.bisq.core.dao.request.compensation.consensus.Restrictions;
|
import io.bisq.core.dao.request.compensation.consensus.Restrictions;
|
||||||
import io.bisq.core.provider.fee.FeeService;
|
import io.bisq.core.provider.fee.FeeService;
|
||||||
|
@ -68,7 +68,7 @@ public class CompensationRequestManager implements PersistedDataHost, BsqBlockCh
|
||||||
private final DaoPeriodService daoPeriodService;
|
private final DaoPeriodService daoPeriodService;
|
||||||
private final BsqWalletService bsqWalletService;
|
private final BsqWalletService bsqWalletService;
|
||||||
private final BtcWalletService btcWalletService;
|
private final BtcWalletService btcWalletService;
|
||||||
private final ReadModel readModel;
|
private final BsqBlockChain bsqBlockChain;
|
||||||
private final Storage<CompensationRequestList> compensationRequestsStorage;
|
private final Storage<CompensationRequestList> compensationRequestsStorage;
|
||||||
private final PublicKey signaturePubKey;
|
private final PublicKey signaturePubKey;
|
||||||
private final FeeService feeService;
|
private final FeeService feeService;
|
||||||
|
@ -90,7 +90,7 @@ public class CompensationRequestManager implements PersistedDataHost, BsqBlockCh
|
||||||
BsqWalletService bsqWalletService,
|
BsqWalletService bsqWalletService,
|
||||||
BtcWalletService btcWalletService,
|
BtcWalletService btcWalletService,
|
||||||
DaoPeriodService daoPeriodService,
|
DaoPeriodService daoPeriodService,
|
||||||
ReadModel readModel,
|
BsqBlockChain bsqBlockChain,
|
||||||
BsqBlockChainChangeDispatcher bsqBlockChainChangeDispatcher,
|
BsqBlockChainChangeDispatcher bsqBlockChainChangeDispatcher,
|
||||||
KeyRing keyRing,
|
KeyRing keyRing,
|
||||||
Storage<CompensationRequestList> compensationRequestsStorage,
|
Storage<CompensationRequestList> compensationRequestsStorage,
|
||||||
|
@ -99,7 +99,7 @@ public class CompensationRequestManager implements PersistedDataHost, BsqBlockCh
|
||||||
this.bsqWalletService = bsqWalletService;
|
this.bsqWalletService = bsqWalletService;
|
||||||
this.btcWalletService = btcWalletService;
|
this.btcWalletService = btcWalletService;
|
||||||
this.daoPeriodService = daoPeriodService;
|
this.daoPeriodService = daoPeriodService;
|
||||||
this.readModel = readModel;
|
this.bsqBlockChain = bsqBlockChain;
|
||||||
this.compensationRequestsStorage = compensationRequestsStorage;
|
this.compensationRequestsStorage = compensationRequestsStorage;
|
||||||
this.feeService = feeService;
|
this.feeService = feeService;
|
||||||
|
|
||||||
|
@ -235,7 +235,7 @@ public class CompensationRequestManager implements PersistedDataHost, BsqBlockCh
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isInPhaseOrUnconfirmed(CompensationRequestPayload payload) {
|
private boolean isInPhaseOrUnconfirmed(CompensationRequestPayload payload) {
|
||||||
return readModel.getTxMap().get(payload.getTxId()) == null || daoPeriodService.isTxInPhase(payload.getTxId(), DaoPeriodService.Phase.COMPENSATION_REQUESTS);
|
return bsqBlockChain.getTxMap().get(payload.getTxId()) == null || daoPeriodService.isTxInPhase(payload.getTxId(), DaoPeriodService.Phase.COMPENSATION_REQUESTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isMine(CompensationRequest compensationRequest) {
|
public boolean isMine(CompensationRequest compensationRequest) {
|
||||||
|
@ -336,7 +336,7 @@ public class CompensationRequestManager implements PersistedDataHost, BsqBlockCh
|
||||||
pastRequests.setPredicate(request -> daoPeriodService.isTxInPastCycle(request.getPayload().getTxId()));
|
pastRequests.setPredicate(request -> daoPeriodService.isTxInPastCycle(request.getPayload().getTxId()));
|
||||||
activeRequests.setPredicate(compensationRequest -> {
|
activeRequests.setPredicate(compensationRequest -> {
|
||||||
return daoPeriodService.isTxInCurrentCycle(compensationRequest.getPayload().getTxId()) ||
|
return daoPeriodService.isTxInCurrentCycle(compensationRequest.getPayload().getTxId()) ||
|
||||||
(readModel.getTxMap().get(compensationRequest.getPayload().getTxId()) == null &&
|
(bsqBlockChain.getTxMap().get(compensationRequest.getPayload().getTxId()) == null &&
|
||||||
isMine(compensationRequest));
|
isMine(compensationRequest));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,17 +4,16 @@ import com.neemre.btcdcli4j.core.BitcoindException;
|
||||||
import com.neemre.btcdcli4j.core.CommunicationException;
|
import com.neemre.btcdcli4j.core.CommunicationException;
|
||||||
import com.neemre.btcdcli4j.core.domain.Block;
|
import com.neemre.btcdcli4j.core.domain.Block;
|
||||||
import io.bisq.common.proto.persistable.PersistenceProtoResolver;
|
import io.bisq.common.proto.persistable.PersistenceProtoResolver;
|
||||||
import io.bisq.core.dao.DaoOptionKeys;
|
|
||||||
import io.bisq.core.dao.blockchain.BsqBlockChain;
|
import io.bisq.core.dao.blockchain.BsqBlockChain;
|
||||||
import io.bisq.core.dao.blockchain.ReadModel;
|
|
||||||
import io.bisq.core.dao.blockchain.WriteModel;
|
|
||||||
import io.bisq.core.dao.blockchain.exceptions.BlockNotConnectingException;
|
import io.bisq.core.dao.blockchain.exceptions.BlockNotConnectingException;
|
||||||
import io.bisq.core.dao.blockchain.exceptions.BsqBlockchainException;
|
import io.bisq.core.dao.blockchain.exceptions.BsqBlockchainException;
|
||||||
import io.bisq.core.dao.blockchain.vo.Tx;
|
import io.bisq.core.dao.blockchain.vo.Tx;
|
||||||
import io.bisq.core.dao.blockchain.vo.TxInput;
|
import io.bisq.core.dao.blockchain.vo.TxInput;
|
||||||
import io.bisq.core.dao.blockchain.vo.TxOutput;
|
import io.bisq.core.dao.blockchain.vo.TxOutput;
|
||||||
import io.bisq.core.dao.blockchain.vo.util.TxIdIndexTuple;
|
import io.bisq.core.dao.blockchain.vo.util.TxIdIndexTuple;
|
||||||
import io.bisq.core.dao.node.consensus.*;
|
import io.bisq.core.dao.node.consensus.BsqTxVerification;
|
||||||
|
import io.bisq.core.dao.node.consensus.IssuanceVerification;
|
||||||
|
import io.bisq.core.dao.node.consensus.OpReturnVerification;
|
||||||
import io.bisq.core.dao.node.full.rpc.RpcService;
|
import io.bisq.core.dao.node.full.rpc.RpcService;
|
||||||
import mockit.Expectations;
|
import mockit.Expectations;
|
||||||
import mockit.Injectable;
|
import mockit.Injectable;
|
||||||
|
@ -24,7 +23,6 @@ import org.bitcoinj.core.Coin;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
import javax.inject.Named;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -35,49 +33,31 @@ import static java.util.Arrays.asList;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
// Intro to jmockit can be found at http://jmockit.github.io/tutorial/Mocking.html
|
|
||||||
|
|
||||||
@RunWith(JMockit.class)
|
@RunWith(JMockit.class)
|
||||||
public class FullNodeParserTest {
|
public class FullNodeParserTest {
|
||||||
// @Tested classes are instantiated automatically when needed in a test case,
|
@Tested(availableDuringSetup = true)
|
||||||
// using injection where possible, see http://jmockit.github.io/tutorial/Mocking.html#tested
|
BsqBlockChain bsqBlockChain;
|
||||||
// To force instantiate earlier, use availableDuringSetup
|
|
||||||
@Tested(fullyInitialized = true, availableDuringSetup = true)
|
@Tested(fullyInitialized = true, availableDuringSetup = true)
|
||||||
FullNodeParser fullNodeParser;
|
FullNodeParser fullNodeParser;
|
||||||
|
|
||||||
@Tested(fullyInitialized = true, availableDuringSetup = true)
|
@Tested(fullyInitialized = true, availableDuringSetup = true)
|
||||||
BsqBlockChain bsqBlockChain;
|
BsqTxVerification bsqTxVerification;
|
||||||
@Tested(availableDuringSetup = true)
|
|
||||||
ReadModel readModel;
|
|
||||||
|
|
||||||
// Used by bsqTxVerification
|
|
||||||
@Tested(fullyInitialized = true, availableDuringSetup = true)
|
|
||||||
TxInputsVerification txInputsVerification;
|
|
||||||
@Tested(fullyInitialized = true, availableDuringSetup = true)
|
|
||||||
TxOutputsVerification txOutputsVerification;
|
|
||||||
|
|
||||||
// @Injectable are mocked resources used to for injecting into @Tested classes
|
|
||||||
// The naming of these resources doesn't matter, any resource that fits will be used for injection
|
|
||||||
|
|
||||||
// Used by bsqBlockChain
|
|
||||||
@Injectable
|
@Injectable
|
||||||
PersistenceProtoResolver persistenceProtoResolver;
|
PersistenceProtoResolver persistenceProtoResolver;
|
||||||
@Injectable
|
@Injectable
|
||||||
File storageDir;
|
File storageDir;
|
||||||
@Injectable
|
@Injectable
|
||||||
String genesisTxId = "genesisTxId";
|
String genesisId = "genesisId";
|
||||||
@Injectable
|
@Injectable
|
||||||
int genesisBlockHeight = 200;
|
int genesisBlockHeight = 200;
|
||||||
|
|
||||||
// Used by fullNodeParser
|
|
||||||
@Injectable
|
@Injectable
|
||||||
RpcService rpcService;
|
RpcService rpcService;
|
||||||
@Tested(fullyInitialized = true, availableDuringSetup = true)
|
@Injectable
|
||||||
WriteModel writeModel;
|
OpReturnVerification opReturnVerification;
|
||||||
@Tested(fullyInitialized = true, availableDuringSetup = true)
|
@Injectable
|
||||||
GenesisTxVerification genesisTxVerification;
|
IssuanceVerification issuanceVerification;
|
||||||
@Tested(fullyInitialized = true, availableDuringSetup = true)
|
|
||||||
BsqTxVerification bsqTxVerification;
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIsBsqTx() {
|
public void testIsBsqTx() {
|
||||||
|
@ -94,18 +74,13 @@ public class FullNodeParserTest {
|
||||||
// 1) - null, 0 -> not BSQ transaction
|
// 1) - null, 0 -> not BSQ transaction
|
||||||
// 2) - 100, null -> BSQ transaction
|
// 2) - 100, null -> BSQ transaction
|
||||||
// 3) - 0, 100 -> BSQ transaction
|
// 3) - 0, 100 -> BSQ transaction
|
||||||
new Expectations(readModel) {{
|
new Expectations(bsqBlockChain) {{
|
||||||
// Expectations can be recorded on mocked instances, either with specific matching arguments or catch all
|
bsqBlockChain.getSpendableTxOutput(new TxIdIndexTuple("tx1", 0));
|
||||||
// http://jmockit.github.io/tutorial/Mocking.html#results
|
|
||||||
// Results are returned in the order they're recorded, so in this case for the first call to
|
|
||||||
// getSpendableTxOutput("tx1", 0) the return value will be Optional.empty()
|
|
||||||
// for the second call the return is Optional.of(new TxOutput(0,... and so on
|
|
||||||
readModel.getSpendableTxOutput(new TxIdIndexTuple("tx1", 0));
|
|
||||||
result = Optional.empty();
|
result = Optional.empty();
|
||||||
result = Optional.of(new TxOutput(0, 100, "txout1", null, null, null, height));
|
result = Optional.of(new TxOutput(0, 100, "txout1", null, null, null, height));
|
||||||
result = Optional.of(new TxOutput(0, 0, "txout1", null, null, null, height));
|
result = Optional.of(new TxOutput(0, 0, "txout1", null, null, null, height));
|
||||||
|
|
||||||
readModel.getSpendableTxOutput(new TxIdIndexTuple("tx1", 1));
|
bsqBlockChain.getSpendableTxOutput(new TxIdIndexTuple("tx1", 1));
|
||||||
result = Optional.of(new TxOutput(0, 0, "txout2", null, null, null, height));
|
result = Optional.of(new TxOutput(0, 0, "txout2", null, null, null, height));
|
||||||
result = Optional.empty();
|
result = Optional.empty();
|
||||||
result = Optional.of(new TxOutput(0, 100, "txout2", null, null, null, height));
|
result = Optional.of(new TxOutput(0, 100, "txout2", null, null, null, height));
|
||||||
|
@ -147,10 +122,10 @@ public class FullNodeParserTest {
|
||||||
Tx cbTx200 = new Tx(cbId200, 200, bh200, time,
|
Tx cbTx200 = new Tx(cbId200, 200, bh200, time,
|
||||||
new ArrayList<TxInput>(),
|
new ArrayList<TxInput>(),
|
||||||
asList(new TxOutput(0, 25, cbId200, null, null, null, 200)));
|
asList(new TxOutput(0, 25, cbId200, null, null, null, 200)));
|
||||||
Tx genesisTx = new Tx(genesisTxId, 200, bh200, time,
|
Tx genesisTx = new Tx(genesisId, 200, bh200, time,
|
||||||
asList(new TxInput("someoldtx", 0)),
|
asList(new TxInput("someoldtx", 0)),
|
||||||
asList(new TxOutput(0, issuance.getValue(), genesisTxId, null, null, null, 200)));
|
asList(new TxOutput(0, issuance.getValue(), genesisId, null, null, null, 200)));
|
||||||
Block block200 = new Block(bh200, 10, 10, 200, 2, "root", asList(cbId200, genesisTxId), time, Long.parseLong("1234"), "bits", BigDecimal.valueOf(1), "chainwork", bh199, bh201);
|
Block block200 = new Block(bh200, 10, 10, 200, 2, "root", asList(cbId200, genesisId), time, Long.parseLong("1234"), "bits", BigDecimal.valueOf(1), "chainwork", bh199, bh201);
|
||||||
|
|
||||||
// Block 201
|
// Block 201
|
||||||
// Make a bsq transaction
|
// Make a bsq transaction
|
||||||
|
@ -162,7 +137,7 @@ public class FullNodeParserTest {
|
||||||
new ArrayList<TxInput>(),
|
new ArrayList<TxInput>(),
|
||||||
asList(new TxOutput(0, 25, cbId201, null, null, null, 201)));
|
asList(new TxOutput(0, 25, cbId201, null, null, null, 201)));
|
||||||
Tx bsqTx1 = new Tx(bsqTx1Id, 201, bh201, time,
|
Tx bsqTx1 = new Tx(bsqTx1Id, 201, bh201, time,
|
||||||
asList(new TxInput(genesisTxId, 0)),
|
asList(new TxInput(genesisId, 0)),
|
||||||
asList(new TxOutput(0, bsqTx1Value1, bsqTx1Id, null, null, null, 201),
|
asList(new TxOutput(0, bsqTx1Value1, bsqTx1Id, null, null, null, 201),
|
||||||
new TxOutput(1, bsqTx1Value2, bsqTx1Id, null, null, null, 201)));
|
new TxOutput(1, bsqTx1Value2, bsqTx1Id, null, null, null, 201)));
|
||||||
Block block201 = new Block(bh201, 10, 10, 201, 2, "root", asList(cbId201, bsqTx1Id), time, Long.parseLong("1234"), "bits", BigDecimal.valueOf(1), "chainwork", bh200, "nextBlockHash");
|
Block block201 = new Block(bh201, 10, 10, 201, 2, "root", asList(cbId201, bsqTx1Id), time, Long.parseLong("1234"), "bits", BigDecimal.valueOf(1), "chainwork", bh200, "nextBlockHash");
|
||||||
|
@ -179,7 +154,7 @@ public class FullNodeParserTest {
|
||||||
result = cbTx199;
|
result = cbTx199;
|
||||||
rpcService.requestTx(cbId200, genesisHeight);
|
rpcService.requestTx(cbId200, genesisHeight);
|
||||||
result = cbTx200;
|
result = cbTx200;
|
||||||
rpcService.requestTx(genesisTxId, genesisHeight);
|
rpcService.requestTx(genesisId, genesisHeight);
|
||||||
result = genesisTx;
|
result = genesisTx;
|
||||||
rpcService.requestTx(cbId201, 201);
|
rpcService.requestTx(cbId201, 201);
|
||||||
result = cbTx201;
|
result = cbTx201;
|
||||||
|
@ -192,25 +167,25 @@ public class FullNodeParserTest {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Verify that the genesis tx has been added to the bsq blockchain with the correct issuance amount
|
// Verify that the genesis tx has been added to the bsq blockchain with the correct issuance amount
|
||||||
assertTrue(readModel.getGenesisTx() == genesisTx);
|
assertTrue(bsqBlockChain.getGenesisTx() == genesisTx);
|
||||||
assertTrue(readModel.getIssuedAmount().getValue() == issuance.getValue());
|
assertTrue(bsqBlockChain.getIssuedAmount().getValue() == issuance.getValue());
|
||||||
|
|
||||||
// And that other txs are not added
|
// And that other txs are not added
|
||||||
assertFalse(readModel.containsTx(cbId199));
|
assertFalse(bsqBlockChain.containsTx(cbId199));
|
||||||
assertFalse(readModel.containsTx(cbId200));
|
assertFalse(bsqBlockChain.containsTx(cbId200));
|
||||||
assertFalse(readModel.containsTx(cbId201));
|
assertFalse(bsqBlockChain.containsTx(cbId201));
|
||||||
|
|
||||||
// But bsq txs are added
|
// But bsq txs are added
|
||||||
assertTrue(readModel.containsTx(bsqTx1Id));
|
assertTrue(bsqBlockChain.containsTx(bsqTx1Id));
|
||||||
TxOutput bsqOut1 = readModel.getSpendableTxOutput(bsqTx1Id, 0).get();
|
TxOutput bsqOut1 = bsqBlockChain.getSpendableTxOutput(bsqTx1Id, 0).get();
|
||||||
assertTrue(bsqOut1.isUnspent());
|
assertTrue(bsqOut1.isUnspent());
|
||||||
assertTrue(bsqOut1.getValue() == bsqTx1Value1);
|
assertTrue(bsqOut1.getValue() == bsqTx1Value1);
|
||||||
TxOutput bsqOut2 = readModel.getSpendableTxOutput(bsqTx1Id, 1).get();
|
TxOutput bsqOut2 = bsqBlockChain.getSpendableTxOutput(bsqTx1Id, 1).get();
|
||||||
assertTrue(bsqOut2.isUnspent());
|
assertTrue(bsqOut2.isUnspent());
|
||||||
assertTrue(bsqOut2.getValue() == bsqTx1Value2);
|
assertTrue(bsqOut2.getValue() == bsqTx1Value2);
|
||||||
assertFalse(readModel.isTxOutputSpendable(genesisTxId, 0));
|
assertFalse(bsqBlockChain.isTxOutputSpendable(genesisId, 0));
|
||||||
assertTrue(readModel.isTxOutputSpendable(bsqTx1Id, 0));
|
assertTrue(bsqBlockChain.isTxOutputSpendable(bsqTx1Id, 0));
|
||||||
assertTrue(readModel.isTxOutputSpendable(bsqTx1Id, 1));
|
assertTrue(bsqBlockChain.isTxOutputSpendable(bsqTx1Id, 1));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue