download transactions for open channels in background

This commit is contained in:
Carsten Otto
2021-11-16 22:18:13 +01:00
parent f50d91251f
commit 8186a342fa
4 changed files with 132 additions and 0 deletions

View File

@@ -0,0 +1,30 @@
package de.cotto.lndmanagej.service;
import de.cotto.lndmanagej.model.Channel;
import de.cotto.lndmanagej.model.ChannelPoint;
import de.cotto.lndmanagej.transactions.service.TransactionService;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
@Component
public class TransactionBackgroundLoader {
private final ChannelService channelService;
private final TransactionService transactionService;
public TransactionBackgroundLoader(ChannelService channelService, TransactionService transactionService) {
this.channelService = channelService;
this.transactionService = transactionService;
}
@Scheduled(fixedDelay = 5, timeUnit = TimeUnit.MINUTES)
public void loadTransactionForOneChannel() {
channelService.getOpenChannels().stream()
.map(Channel::getChannelPoint)
.map(ChannelPoint::getTransactionHash)
.filter(transactionService::isUnknown)
.findAny()
.ifPresent(transactionService::getTransaction);
}
}

View File

@@ -0,0 +1,80 @@
package de.cotto.lndmanagej.service;
import de.cotto.lndmanagej.model.LocalOpenChannel;
import de.cotto.lndmanagej.transactions.service.TransactionService;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.util.Set;
import static de.cotto.lndmanagej.model.BalanceInformationFixtures.BALANCE_INFORMATION;
import static de.cotto.lndmanagej.model.ChannelFixtures.CAPACITY;
import static de.cotto.lndmanagej.model.ChannelIdFixtures.CHANNEL_ID;
import static de.cotto.lndmanagej.model.ChannelIdFixtures.CHANNEL_ID_2;
import static de.cotto.lndmanagej.model.ChannelIdFixtures.CHANNEL_ID_3;
import static de.cotto.lndmanagej.model.ChannelPointFixtures.CHANNEL_POINT;
import static de.cotto.lndmanagej.model.ChannelPointFixtures.CHANNEL_POINT_2;
import static de.cotto.lndmanagej.model.ChannelPointFixtures.CHANNEL_POINT_3;
import static de.cotto.lndmanagej.model.LocalOpenChannelFixtures.LOCAL_OPEN_CHANNEL;
import static de.cotto.lndmanagej.model.LocalOpenChannelFixtures.LOCAL_OPEN_CHANNEL_2;
import static de.cotto.lndmanagej.model.PubkeyFixtures.PUBKEY;
import static de.cotto.lndmanagej.model.PubkeyFixtures.PUBKEY_2;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class TransactionBackgroundLoaderTest {
@InjectMocks
private TransactionBackgroundLoader transactionBackgroundLoader;
@Mock
private TransactionService transactionService;
@Mock
private ChannelService channelService;
@Test
void update_no_channel() {
transactionBackgroundLoader.loadTransactionForOneChannel();
verify(transactionService, never()).getTransaction(any());
}
@Test
void update_all_known() {
when(channelService.getOpenChannels()).thenReturn(Set.of(LOCAL_OPEN_CHANNEL, LOCAL_OPEN_CHANNEL_2));
when(transactionService.isUnknown(any())).thenReturn(false);
transactionBackgroundLoader.loadTransactionForOneChannel();
verify(transactionService, never()).getTransaction(any());
}
@Test
void update_all_unknown() {
when(channelService.getOpenChannels()).thenReturn(Set.of(LOCAL_OPEN_CHANNEL, LOCAL_OPEN_CHANNEL_2));
when(transactionService.isUnknown(any())).thenReturn(true);
transactionBackgroundLoader.loadTransactionForOneChannel();
verify(transactionService, times(1)).getTransaction(any());
}
@Test
void update_one_unknown() {
LocalOpenChannel channel1 =
new LocalOpenChannel(CHANNEL_ID, CHANNEL_POINT, CAPACITY, PUBKEY, PUBKEY_2, BALANCE_INFORMATION);
LocalOpenChannel channel2 =
new LocalOpenChannel(CHANNEL_ID_2, CHANNEL_POINT_2, CAPACITY, PUBKEY, PUBKEY_2, BALANCE_INFORMATION);
LocalOpenChannel channel3 =
new LocalOpenChannel(CHANNEL_ID_3, CHANNEL_POINT_3, CAPACITY, PUBKEY, PUBKEY_2, BALANCE_INFORMATION);
when(channelService.getOpenChannels()).thenReturn(Set.of(channel1, channel2, channel3));
String unknownHash = CHANNEL_POINT_3.getTransactionHash();
when(transactionService.isUnknown(unknownHash)).thenReturn(true);
transactionBackgroundLoader.loadTransactionForOneChannel();
verify(transactionService, times(1)).getTransaction(unknownHash);
}
}

View File

@@ -28,6 +28,14 @@ public class TransactionService {
return downloadAndPersist(transactionHash);
}
public boolean isKnown(String transactionHash) {
return transactionDao.getTransaction(transactionHash).isPresent();
}
public boolean isUnknown(String transactionHash) {
return !isKnown(transactionHash);
}
private Optional<Transaction> downloadAndPersist(String transactionHash) {
Optional<Transaction> optionalTransaction = transactionProvider.get(transactionHash);
optionalTransaction.ifPresent(transactionDao::saveTransaction);

View File

@@ -57,4 +57,18 @@ class TransactionServiceTest {
assertThat(transactionService.getTransaction(TRANSACTION_HASH)).isEmpty();
verify(transactionDao, never()).saveTransaction(any());
}
@Test
void isKnown_false() {
when(transactionDao.getTransaction(TRANSACTION_HASH)).thenReturn(Optional.empty());
assertThat(transactionService.isKnown(TRANSACTION_HASH)).isFalse();
assertThat(transactionService.isUnknown(TRANSACTION_HASH)).isTrue();
}
@Test
void isKnown_true() {
when(transactionDao.getTransaction(TRANSACTION_HASH)).thenReturn(Optional.of(TRANSACTION));
assertThat(transactionService.isKnown(TRANSACTION_HASH)).isTrue();
assertThat(transactionService.isUnknown(TRANSACTION_HASH)).isFalse();
}
}