Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Speed up bond repository update and remove some raw types #7082

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions core/src/main/java/bisq/core/dao/DaoFacade.java
Original file line number Diff line number Diff line change
Expand Up @@ -598,14 +598,14 @@ public Optional<Integer> getLockTime(String txId) {
}


public List<Bond> getAllBonds() {
List<Bond> bonds = new ArrayList<>(bondedReputationRepository.getBonds());
public List<Bond<?>> getAllBonds() {
List<Bond<?>> bonds = new ArrayList<>(bondedReputationRepository.getBonds());
bonds.addAll(bondedRolesRepository.getBonds());
return bonds;
}

public List<Bond> getAllActiveBonds() {
List<Bond> bonds = new ArrayList<>(bondedReputationRepository.getActiveBonds());
public List<Bond<?>> getAllActiveBonds() {
List<Bond<?>> bonds = new ArrayList<>(bondedReputationRepository.getActiveBonds());
bonds.addAll(bondedRolesRepository.getActiveBonds());
return bonds;
}
Expand Down Expand Up @@ -739,7 +739,7 @@ public boolean isMyRole(Role role) {
return bondedRolesRepository.isMyRole(role);
}

public Optional<Bond> getBondByLockupTxId(String lockupTxId) {
public Optional<Bond<?>> getBondByLockupTxId(String lockupTxId) {
return getAllBonds().stream().filter(e -> lockupTxId.equals(e.getLockupTxId())).findAny();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,7 @@ Map<String, BurningManCandidate> getBurningManCandidatesByName(int chainHeight,
daoStateService.getGenesisTx()
.ifPresent(tx -> tx.getTxOutputs().forEach(txOutput -> {
String name = GENESIS_OUTPUT_PREFIX + txOutput.getIndex();
burningManCandidatesByName.putIfAbsent(name, new BurningManCandidate());
BurningManCandidate candidate = burningManCandidatesByName.get(name);
BurningManCandidate candidate = burningManCandidatesByName.computeIfAbsent(name, n -> new BurningManCandidate());

// Issuance
int issuanceHeight = txOutput.getBlockHeight();
Expand Down Expand Up @@ -262,8 +261,7 @@ Map<P2PDataStorage.ByteArray, Set<TxOutput>> getProofOfBurnOpReturnTxOutputByHas
.filter(txOutput -> txOutput.getBlockHeight() <= chainHeight)
.forEach(txOutput -> {
P2PDataStorage.ByteArray key = new P2PDataStorage.ByteArray(ProofOfBurnConsensus.getHashFromOpReturnData(txOutput.getOpReturnData()));
map.putIfAbsent(key, new HashSet<>());
map.get(key).add(txOutput);
map.computeIfAbsent(key, k -> new HashSet<>()).add(txOutput);
});
return map;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
import bisq.core.dao.state.model.blockchain.TxOutput;
import bisq.core.dao.state.model.blockchain.TxType;

import com.google.protobuf.ByteString;

import org.bitcoinj.core.Sha256Hash;
import org.bitcoinj.core.Transaction;
import org.bitcoinj.core.TransactionInput;
Expand Down Expand Up @@ -56,14 +58,17 @@
* unconfirmed txs.
*/
@Slf4j
public abstract class BondRepository<T extends Bond, R extends BondedAsset> implements DaoSetupService,
public abstract class BondRepository<B extends Bond<T>, T extends BondedAsset> implements DaoSetupService,
BsqWalletService.WalletTransactionsChangeListener {

///////////////////////////////////////////////////////////////////////////////////////////
// Static
///////////////////////////////////////////////////////////////////////////////////////////

public static void applyBondState(DaoStateService daoStateService, Bond bond, Tx lockupTx, TxOutput lockupTxOutput) {
public static void applyBondState(DaoStateService daoStateService,
Bond<?> bond,
Tx lockupTx,
TxOutput lockupTxOutput) {
if (bond.getBondState() != BondState.LOCKUP_TX_PENDING || bond.getBondState() != BondState.UNLOCK_TX_PENDING)
bond.setBondState(BondState.LOCKUP_TX_CONFIRMED);

Expand Down Expand Up @@ -110,7 +115,9 @@ public static boolean isLockupTxUnconfirmed(BsqWalletService bsqWalletService, B
.anyMatch(data -> Arrays.equals(BondConsensus.getHashFromOpReturnData(data), bondedAsset.getHash()));
}

public static boolean isUnlockTxUnconfirmed(BsqWalletService bsqWalletService, DaoStateService daoStateService, BondedAsset bondedAsset) {
public static boolean isUnlockTxUnconfirmed(BsqWalletService bsqWalletService,
DaoStateService daoStateService,
BondedAsset bondedAsset) {
return bsqWalletService.getPendingWalletTransactionsStream()
.filter(transaction -> transaction.getInputs().size() > 1)
.flatMap(transaction -> transaction.getInputs().stream()) // We need to iterate all inputs
Expand All @@ -127,7 +134,7 @@ public static boolean isUnlockTxUnconfirmed(BsqWalletService bsqWalletService, D
.anyMatch(data -> Arrays.equals(BondConsensus.getHashFromOpReturnData(data), bondedAsset.getHash()));
}

public static boolean isConfiscated(Bond bond, DaoStateService daoStateService) {
public static boolean isConfiscated(Bond<?> bond, DaoStateService daoStateService) {
return (bond.getLockupTxId() != null && daoStateService.isConfiscatedLockupTxOutput(bond.getLockupTxId())) ||
(bond.getUnlockTxId() != null && daoStateService.isConfiscatedUnlockTxOutput(bond.getUnlockTxId()));
}
Expand All @@ -136,10 +143,11 @@ public static boolean isConfiscated(Bond bond, DaoStateService daoStateService)
protected final DaoStateService daoStateService;
protected final BsqWalletService bsqWalletService;

// This map is just for convenience. The data which are used to fill the map are stored in the DaoState (role, txs).
protected final Map<String, T> bondByUidMap = new HashMap<>();
// These maps are just for convenience. The data which are used to fill the maps are stored in the DaoState (role, txs).
protected final Map<String, B> bondByUidMap = new HashMap<>();
private Map<ByteString, T> bondedAssetByHashMap;
@Getter
protected final ObservableList<T> bonds = FXCollections.observableArrayList();
protected final ObservableList<B> bonds = FXCollections.observableArrayList();


///////////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -187,12 +195,12 @@ public void onWalletTransactionsChange() {
// API
///////////////////////////////////////////////////////////////////////////////////////////

public boolean isBondedAssetAlreadyInBond(R bondedAsset) {
public boolean isBondedAssetAlreadyInBond(T bondedAsset) {
boolean contains = bondByUidMap.containsKey(bondedAsset.getUid());
return contains && bondByUidMap.get(bondedAsset.getUid()).getLockupTxId() != null;
}

public List<Bond> getActiveBonds() {
public List<B> getActiveBonds() {
return bonds.stream().filter(Bond::isActive).collect(Collectors.toList());
}

Expand All @@ -201,28 +209,35 @@ public List<Bond> getActiveBonds() {
// Protected
///////////////////////////////////////////////////////////////////////////////////////////

protected abstract T createBond(R bondedAsset);
protected abstract B createBond(T bondedAsset);

protected abstract void updateBond(B bond, T bondedAsset, TxOutput lockupTxOutput);

protected abstract void updateBond(T bond, R bondedAsset, TxOutput lockupTxOutput);
protected abstract Stream<T> getBondedAssetStream();

protected abstract Stream<R> getBondedAssetStream();
protected Map<ByteString, T> getBondedAssetByHashMap() {
return bondedAssetByHashMap != null ? bondedAssetByHashMap
: (bondedAssetByHashMap = getBondedAssetStream()
.collect(Collectors.toMap(a -> ByteString.copyFrom(a.getHash()), a -> a, (a, b) -> a)));
}

protected void update() {
long ts = System.currentTimeMillis();
log.debug("update");
bondedAssetByHashMap = null;
getBondedAssetStream().forEach(bondedAsset -> {
String uid = bondedAsset.getUid();
bondByUidMap.putIfAbsent(uid, createBond(bondedAsset));
T bond = bondByUidMap.get(uid);
B bond = bondByUidMap.computeIfAbsent(uid, u -> createBond(bondedAsset));

daoStateService.getLockupTxOutputs().forEach(lockupTxOutput -> {
updateBond(bond, bondedAsset, lockupTxOutput);
});
daoStateService.getLockupTxOutputs().forEach(lockupTxOutput ->
updateBond(bond, bondedAsset, lockupTxOutput));
});

updateBondStateFromUnconfirmedLockupTxs();
updateBondStateFromUnconfirmedUnlockTxs();

bonds.setAll(bondByUidMap.values());
log.debug("update took {} ms", System.currentTimeMillis() - ts);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,13 @@
import bisq.core.dao.state.model.governance.Role;
import bisq.core.dao.state.model.governance.RoleProposal;

import com.google.protobuf.ByteString;

import org.bitcoinj.core.Sha256Hash;
import org.bitcoinj.core.Transaction;

import javax.inject.Inject;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.Set;
Expand Down Expand Up @@ -107,18 +108,12 @@ protected void updateBond(BondedRole bond, Role bondedAsset, TxOutput lockupTxOu
// We used the hash of the bonded bondedAsset object as our hash in OpReturn of the lock up tx to have a
// unique binding of the tx to the data object.
byte[] hash = BondConsensus.getHashFromOpReturnData(opReturnData);
Optional<Role> candidate = findBondedAssetByHash(hash);
if (candidate.isPresent() && bondedAsset.equals(candidate.get()))
Role candidateOrNull = getBondedAssetByHashMap().get(ByteString.copyFrom(hash));
if (bondedAsset.equals(candidateOrNull))
applyBondState(daoStateService, bond, lockupTx, lockupTxOutput);
});
}

private Optional<Role> findBondedAssetByHash(byte[] hash) {
return getBondedAssetStream()
.filter(bondedAsset -> Arrays.equals(bondedAsset.getHash(), hash))
.findAny();
}

private Stream<RoleProposal> getBondedRoleProposalStream() {
return daoStateService.getEvaluatedProposalList().stream()
.filter(evaluatedProposal -> evaluatedProposal.getProposal() instanceof RoleProposal)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,15 @@
import org.jetbrains.annotations.Nullable;

@Slf4j
abstract class RequestStateHashesHandler<Req extends GetStateHashesRequest, Res extends GetStateHashesResponse> implements MessageListener {
abstract class RequestStateHashesHandler<Req extends GetStateHashesRequest, Res extends GetStateHashesResponse<?>> implements MessageListener {
private static final long TIMEOUT = 180;


///////////////////////////////////////////////////////////////////////////////////////////
// Listener
///////////////////////////////////////////////////////////////////////////////////////////

public interface Listener<Res extends GetStateHashesResponse> {
public interface Listener<Res extends GetStateHashesResponse<?>> {
void onComplete(Res getStateHashesResponse, Optional<NodeAddress> peersNodeAddress);

@SuppressWarnings("UnusedParameters")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,13 @@
import javax.annotation.Nullable;

@Slf4j
public abstract class StateNetworkService<Msg extends NewStateHashMessage,
public abstract class StateNetworkService<Msg extends NewStateHashMessage<StH>,
Req extends GetStateHashesRequest,
Res extends GetStateHashesResponse<StH>,
Han extends RequestStateHashesHandler,
Han extends RequestStateHashesHandler<Req, Res>,
StH extends StateHash> implements MessageListener {

public interface Listener<Msg extends NewStateHashMessage, Req extends GetStateHashesRequest, StH extends StateHash> {
public interface Listener<Msg extends NewStateHashMessage<StH>, Req extends GetStateHashesRequest, StH extends StateHash> {
void onNewStateHashMessage(Msg newStateHashMessage, Connection connection);

void onGetStateHashRequest(Connection connection, Req getStateHashRequest);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
*/
@Immutable
@Value
public final class TxOutputKey implements ImmutableDaoStateModel, Comparable {
public final class TxOutputKey implements ImmutableDaoStateModel, Comparable<Object> {
private final String txId;
private final int index;

Expand All @@ -47,7 +47,7 @@ public String toString() {

public static TxOutputKey getKeyFromString(String keyAsString) {
final String[] tokens = keyAsString.split(":");
return new TxOutputKey(tokens[0], Integer.valueOf(tokens[1]));
return new TxOutputKey(tokens[0], Integer.parseInt(tokens[1]));
}

@Override
Expand Down
4 changes: 2 additions & 2 deletions core/src/main/java/bisq/core/locale/CurrencyUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ public static List<TradeCurrency> getAllFiatCurrencies() {
return new ArrayList<>(fiatCurrencyMapSupplier.get().values());
}

public static Collection<FiatCurrency> getAllSortedFiatCurrencies(Comparator comparator) {
return (List<FiatCurrency>) getAllSortedFiatCurrencies().stream()
public static Collection<FiatCurrency> getAllSortedFiatCurrencies(Comparator<? super FiatCurrency> comparator) {
return getAllSortedFiatCurrencies().stream()
.sorted(comparator) // sorted by comparator param
.collect(Collectors.toList());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,24 @@

import javafx.beans.property.SimpleIntegerProperty;

import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
public class MyProposalListServiceTest {
@Test
public void canInstantiate() {
public void canInstantiate(@Mock PersistenceManager<MyProposalList> persistenceManager) {
P2PService p2PService = mock(P2PService.class);
when(p2PService.getNumConnectedPeers()).thenReturn(new SimpleIntegerProperty(0));
PersistenceManager persistenceManager = mock(PersistenceManager.class);
MyProposalListService service = new MyProposalListService(p2PService,
mock(DaoStateService.class),
mock(PeriodService.class), mock(WalletsManager.class), persistenceManager, mock(PubKeyRing.class)

new MyProposalListService(p2PService, mock(DaoStateService.class), mock(PeriodService.class),
mock(WalletsManager.class), persistenceManager, mock(PubKeyRing.class)
);
}
}
Loading