All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.provenance.eventstream.stream.flows.WsBlockHeaderFlow.kt Maven / Gradle / Ivy

The newest version!
package io.provenance.eventstream.stream.flows

import com.tinder.scarlet.lifecycle.LifecycleRegistry
import com.tinder.scarlet.retry.BackoffStrategy
import io.provenance.eventstream.decoder.DecoderAdapter
import io.provenance.eventstream.defaultBackoffStrategy
import io.provenance.eventstream.defaultLifecycle
import io.provenance.eventstream.defaultWebSocketChannel
import io.provenance.eventstream.net.NetAdapter
import io.provenance.eventstream.stream.WebSocketChannel
import io.provenance.eventstream.stream.WebSocketService
import io.provenance.eventstream.stream.models.BlockHeader
import io.provenance.eventstream.stream.models.BlockMeta
import io.provenance.eventstream.stream.rpc.response.MessageType
import io.provenance.eventstream.stream.withLifecycle
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.asFlow
import kotlinx.coroutines.flow.map
import kotlin.time.Duration

/**
 * Convert a [Flow] of type [MessageType.NewBlockHeader] into a flow of [BlockHeader]
 */
fun Flow.mapLiveBlockHeader(): Flow = map { it.header.data.value!!.header!! }

/**
 * Create a [Flow] of historical [BlockMeta] from a node.
 *
 * Convenience wrapper around [nodeEventStream] and [mapLiveBlockHeader]
 *
 * @param netAdapter The [NetAdapter] to use to connect to the node.
 * @param decoderAdapter The [DecoderAdapter] to use to convert from json.
 * @param throttle The web socket throttle duration.
 * @param lifecycle The [LifecycleRegistry] instance used to manage startup and shutdown.
 * @param channel The [WebSocketChannel] used to receive incoming websocket events.
 * @param wss The [WebSocketService] used to manage the channel.
 */
fun wsBlockHeaderFlow(
    netAdapter: NetAdapter,
    decoderAdapter: DecoderAdapter,
    throttle: Duration = DEFAULT_THROTTLE_PERIOD,
    lifecycle: LifecycleRegistry = defaultLifecycle(throttle),
    backoffStrategy: BackoffStrategy = defaultBackoffStrategy(),
    channel: WebSocketChannel = defaultWebSocketChannel(netAdapter.wsAdapter, decoderAdapter.wsDecoder, throttle, lifecycle, backoffStrategy),
    wss: WebSocketService = channel.withLifecycle(lifecycle),
): Flow {
    val fetcher: suspend (List) -> Flow = {
        it.chunked(20).flatMap { range ->
            netAdapter.rpcAdapter.getBlocksMeta(range.first(), range.last()).orEmpty().sortedBy { it.header!!.height }
        }.asFlow().mapHistoricalHeaderData()
    }

    return nodeEventStream(netAdapter, decoderAdapter, throttle, lifecycle, backoffStrategy, channel, wss)
        .mapLiveBlockHeader()
        .contiguous(fetcher) { it.height }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy