ronantakizawa/codereview-bench huggingface dataset:
Repository: thunderbird/thunderbird-android
File: feature/notification/api/build.gradle.kts (Kotlin)

Code before:
plugins {
    id(ThunderbirdPlugins.Library.kmpCompose)
    alias(libs.plugins.dev.mokkery)
}

kotlin {
    androidLibrary {
        namespace = "net.thunderbird.feature.notification.api"
        androidResources {
            enable = true
        }
        withHostTestBuilder {}.configure {
            isIncludeAndroidResources = true
        }
    }
    sourceSets {
        commonMain.dependencies {
            implementation(projects.core.common)
            implementation(projects.core.featureflag)
            implementation(projects.core.outcome)
        }
        commonTest.dependencies {
            implementation(projects.feature.notification.testing)
        }
        androidMain.dependencies {
            implementation(projects.core.ui.compose.designsystem)
            implementation(projects.core.ui.compose.theme2.common)
        }
        getByName("androidHostTest").dependencies {
            implementation(projects.core.ui.compose.testing)
            implementation(libs.bundles.shared.jvm.test.compose)
            implementation(libs.bundles.shared.jvm.android.compose.debug)
        }
        jvmTest.dependencies {
            implementation(libs.kotlinx.coroutines.test)
            implementation(libs.bundles.shared.jvm.test)
        }
    }


Review comment (suggestion):
Should be:

```suggestion
        withHostTest {
            isIncludeAndroidResources = true
        }
```

Code after:
plugins {
    id(ThunderbirdPlugins.Library.kmpCompose)
    alias(libs.plugins.dev.mokkery)
}

kotlin {
    androidLibrary {
        namespace = "net.thunderbird.feature.notification.api"
        @Suppress("UnstableApiUsage")
        androidResources {
            enable = true
        }
        withHostTest {
            isIncludeAndroidResources = true
        }
    }
    sourceSets {
        commonMain.dependencies {
            implementation(projects.core.common)
            implementation(projects.core.featureflag)
            implementation(projects.core.outcome)
        }
        commonTest.dependencies {
            implementation(projects.feature.notification.testing)
        }
        androidMain.dependencies {
            implementation(projects.core.ui.compose.designsystem)
            implementation(projects.core.ui.compose.theme2.common)
        }
        androidHostTest.dependencies {
            implementation(projects.core.ui.compose.testing)
            implementation(libs.bundles.shared.jvm.test.compose)
            implementation(libs.bundles.shared.jvm.android.compose.debug)
        }
        jvmTest.dependencies {
            implementation(libs.kotlinx.coroutines.test)
            implementation(libs.bundles.shared.jvm.test)
        }
    }
Repository: thunderbird/thunderbird-android
File: core/logging/impl-console/build.gradle.kts (Kotlin)

Code before:
import com.android.build.api.dsl.KotlinMultiplatformAndroidCompilation
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi

plugins {
    id(ThunderbirdPlugins.Library.kmp)
}

kotlin {
    androidLibrary {
        namespace = "net.thunderbird.core.logging.console"
    }
    @OptIn(ExperimentalKotlinGradlePluginApi::class)
    applyDefaultHierarchyTemplate {
        common {
            group("commonJvm") {
                // workaround for https://issuetracker.google.com/issues/442950553
                withCompilations { it is KotlinMultiplatformAndroidCompilation }
                withJvm()
            }
        }
    }
    sourceSets {
        val commonJvmMain by getting

        commonMain.dependencies {
            implementation(projects.core.logging.api)
        }

        androidMain.dependencies {
            implementation(libs.timber)
        }
    }
}


Review comment (suggestion):
This needs `withHostTest`


```suggestion
        namespace = "net.thunderbird.core.logging.console"
        withHostTest {  }
```

Code after:
import com.android.build.api.dsl.KotlinMultiplatformAndroidCompilation
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi

plugins {
    id(ThunderbirdPlugins.Library.kmp)
}

kotlin {
    androidLibrary {
        namespace = "net.thunderbird.core.logging.console"
        withHostTest {}
    }
    @OptIn(ExperimentalKotlinGradlePluginApi::class)
    applyDefaultHierarchyTemplate {
        common {
            group("commonJvm") {
                // workaround for https://issuetracker.google.com/issues/442950553
                withCompilations { it is KotlinMultiplatformAndroidCompilation }
                withJvm()
            }
        }
    }
    sourceSets {
        val commonJvmMain by getting

        commonMain.dependencies {
            implementation(projects.core.logging.api)
        }

        androidMain.dependencies {
            implementation(libs.timber)
        }
    }
}
Repository: thunderbird/thunderbird-android
File: feature/account/settings/impl/src/main/kotlin/net/thunderbird/feature/account/settings/impl/ui/general/GeneralSettingsScreen.kt (Kotlin)

Code before:
import net.thunderbird.feature.account.settings.impl.ui.general.GeneralSettingsContract.SettingsBuilder
import org.koin.androidx.compose.koinViewModel
import org.koin.compose.koinInject
import org.koin.core.parameter.parametersOf

@Composable
internal fun GeneralSettingsScreen(
    accountId: AccountId,
    onBack: () -> Unit,
    viewModel: GeneralSettingsContract.ViewModel = koinViewModel<GeneralSettingsViewModel> {
        parametersOf(accountId)
    },
    provider: SettingViewProvider = koinInject(),
    builder: SettingsBuilder = koinInject(),
) {
    val imagePicker = rememberLauncherForActivityResult(ActivityResultContracts.GetContent()) { uri ->
        if (uri != null) {
            viewModel.event(Event.OnAvatarImagePicked(uri.toKmpUri()))
        }
    }

    val (state, dispatch) = viewModel.observe { effect ->
        when (effect) {
            is Effect.NavigateBack -> onBack()
            is Effect.OpenAvatarImagePicker -> {
                imagePicker.launch("image/*")
            }
        }
    }

    BackHandler(onBack = onBack)

    GeneralSettingsContent(
        state = state.value,
        onEvent = { dispatch(it) },
        provider = provider,
        builder = builder,
    )
}


Review comment (bug):
This allows any image selection and will result in a failure when the image is not accepted.

You could limit the selection by changing the `ActivityResultContracts.GetContent()` to `ActivityResultContracts.OpenDocument()` and provide an array of of "image/jpeg", "image/png" instead.

Code after:
import net.thunderbird.feature.account.settings.impl.ui.general.GeneralSettingsContract.SettingsBuilder
import org.koin.androidx.compose.koinViewModel
import org.koin.compose.koinInject
import org.koin.core.parameter.parametersOf

@Composable
internal fun GeneralSettingsScreen(
    accountId: AccountId,
    onBack: () -> Unit,
    viewModel: GeneralSettingsContract.ViewModel = koinViewModel<GeneralSettingsViewModel> {
        parametersOf(accountId)
    },
    provider: SettingViewProvider = koinInject(),
    builder: SettingsBuilder = koinInject(),
) {
    val imagePicker = rememberLauncherForActivityResult(ActivityResultContracts.OpenDocument()) { uri ->
        if (uri != null) {
            viewModel.event(Event.OnAvatarImagePicked(uri.toKmpUri()))
        }
    }

    val (state, dispatch) = viewModel.observe { effect ->
        when (effect) {
            is Effect.NavigateBack -> onBack()
            is Effect.OpenAvatarImagePicker -> {
                imagePicker.launch(arrayOf("image/jpeg", "image/png"))
            }
        }
    }

    BackHandler(onBack = onBack)

    GeneralSettingsContent(
        state = state.value,
        onEvent = { dispatch(it) },
        provider = provider,
        builder = builder,
    )
}
Repository: twintproject/twint
File: twint/output.py (Python)

Code before:
from . import format, get
from .tweet import Tweet
from .user import User
from .storage import db, elasticsearch, write, panda

import logging as logme

follows_list = []
tweets_list = []
users_list = []

author_list = {''}
author_list.pop()

# used by Pandas
_follows_object = {}


def _formatDateTime(datetimestamp):
    try:
        return int(datetime.strptime(datetimestamp, "%Y-%m-%d %H:%M:%S").timestamp())
    except ValueError:
        try:
            return int(datetime.strptime(datetimestamp, "%d-%m-%Y %H:%M:%S").timestamp())
        except ValueError:
            return int(datetime.strptime(datetimestamp, "%Y-%m-%d").timestamp())


def _clean_follow_list():
    logme.debug(__name__ + ':clean_follow_list')
    global _follows_object
    _follows_object = {}


def clean_lists():
    logme.debug(__name__ + ':clean_lists')
    global follows_list
    global tweets_list
    global users_list
    follows_list = []
    tweets_list = []
    users_list = []


def datecheck(datetimestamp, config):
    logme.debug(__name__ + ':datecheck')
    if config.Since:
        logme.debug(__name__ + ':datecheck:SinceTrue')

        d = _formatDateTime(datetimestamp)
        s = _formatDateTime(config.Since)

Review comment (bug):
I investigated this error and found that I was parsing the string incorrectly (my bad, I wasn't familiar with twint when I coded that), so If you simply replace `'%Y-%m-%d'` with `'%Y-%m-%d'` in tweet.py line 174, 176. users.py line 30. you won't need to add this line.
So what I previously did was parsed the string with a different format (dd-mm-yyyy) than what twint follows (yyyy-mm-dd) so it created some issue, so it's better to revert those parsed values to keep the date consistent throughout.

Code after:
from . import format, get
from .tweet import Tweet
from .user import User
from .storage import db, elasticsearch, write, panda

import logging as logme

follows_list = []
tweets_list = []
users_list = []

author_list = {''}
author_list.pop()

# used by Pandas
_follows_object = {}


def _formatDateTime(datetimestamp):
    try:
        return int(datetime.strptime(datetimestamp, "%Y-%m-%d %H:%M:%S").timestamp())
    except ValueError:
        return int(datetime.strptime(datetimestamp, "%Y-%m-%d").timestamp())


def _clean_follow_list():
    logme.debug(__name__ + ':clean_follow_list')
    global _follows_object
    _follows_object = {}


def clean_lists():
    logme.debug(__name__ + ':clean_lists')
    global follows_list
    global tweets_list
    global users_list
    follows_list = []
    tweets_list = []
    users_list = []


def datecheck(datetimestamp, config):
    logme.debug(__name__ + ':datecheck')
    if config.Since:
        logme.debug(__name__ + ':datecheck:SinceTrue')

        d = _formatDateTime(datetimestamp)
        s = _formatDateTime(config.Since)

        if d < s:
            return False
Repository: unionlabs/union
File: site/src/components/LogoVariable.svelte (Svelte)

Code before:
<script lang="ts"> 
	let cubeWidth = 15;
	$: cubeDelta = (20 - cubeWidth) / 2;
</script>

<div class="flex flex-col gap-20 items-center justify-center min-h-screen mx-6">
	<svg width="500px" height="500px" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
		<rect x={60 + cubeDelta } y={30 + cubeDelta} width={cubeWidth} height={cubeWidth} fill="white"/>
		<rect x={40 + cubeDelta} y={30 + cubeDelta} width={cubeWidth} height={cubeWidth} fill="white"/>
		<rect x={20 + cubeDelta} y={30 + cubeDelta} width={cubeWidth} height={cubeWidth} fill="white"/>
		<rect x = {cubeDelta} y={30 + cubeDelta} width={cubeWidth} height={cubeWidth} fill="white"/>
		<path transform={`translate(20, ${-cubeDelta})`} d="M50 30C50 18.9543 41.0457 10 30 10C18.9543 10 10 18.9543 10 30"  stroke="white" stroke-width={cubeWidth}/>
		<path transform={`translate(-20, ${cubeDelta})`} d="M30 50C30 61.0457 38.9543 70 50 70C61.0457 70 70 61.0457 70 50" stroke="white" stroke-width={cubeWidth}/>
	</svg>
	<input class="w-full max-w-80" type=range min=0 max=20 step=0.01 bind:value={cubeWidth} />
</div>

<style>
	:global(body) {
		background-color: black;
	}
</style>


Review comment (suggestion):
This fixes the following error in the console at https://union.build/logo-variable/:
```sh
Error:
<path> attribute d: Unexpected end of attribute. Expected number, "…1.0457 70 50L30 ".
```

Code after:
<script lang="ts"> 
	let cubeWidth = 15;
	$: cubeDelta = (20 - cubeWidth) / 2;
</script>

<div class="flex flex-col gap-20 items-center justify-center min-h-screen mx-6">
	<svg width="500px" height="500px" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
		<rect x={60 + cubeDelta } y={30 + cubeDelta} width={cubeWidth} height={cubeWidth} fill="white"/>
		<rect x={40 + cubeDelta} y={30 + cubeDelta} width={cubeWidth} height={cubeWidth} fill="white"/>
		<rect x={20 + cubeDelta} y={30 + cubeDelta} width={cubeWidth} height={cubeWidth} fill="white"/>
		<rect x = {cubeDelta} y={30 + cubeDelta} width={cubeWidth} height={cubeWidth} fill="white"/>
		<path transform={`translate(20, ${-cubeDelta})`} d="M50 30C50 18.9543 41.0457 10 30 10C18.9543 10 10 18.9543 10 30"  stroke="white" stroke-width={cubeWidth}/>
		<path transform={`translate(-20, ${cubeDelta})`} d="M30 50C30 61.0457 38.9543 70 50 70C61.0457 70 70 61.0457 70 50" stroke="white" stroke-width={cubeWidth}/>
	</svg>
	<label class="sr-only" for="range-slider">Thickness range:</label>
	<input id="range-slider" class="w-full max-w-80" type=range min=0 max=20 step=0.01 bind:value={cubeWidth} />
</div>

<style>
	:global(body) {
		background-color: black;
	}
</style>
Repository: unionlabs/union
File: site/src/components/LogoVariable.svelte (Svelte)

Code before:
<script lang="ts"> 
	let cubeWidth = 15;
	$: cubeDelta = (20 - cubeWidth) / 2;
</script>

<div class="flex flex-col gap-20 items-center justify-center min-h-screen">
	<svg width="500px" height="500px" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
		<rect x={60 + cubeDelta } y={30 + cubeDelta} width={cubeWidth} height={cubeWidth} fill="white"/>
		<rect x={40 + cubeDelta} y={30 + cubeDelta} width={cubeWidth} height={cubeWidth} fill="white"/>
		<rect x={20 + cubeDelta} y={30 + cubeDelta} width={cubeWidth} height={cubeWidth} fill="white"/>
		<rect x = {cubeDelta} y={30 + cubeDelta} width={cubeWidth} height={cubeWidth} fill="white"/>
		<path transform={`translate(20, ${-cubeDelta})`} d="M50 30C50 18.9543 41.0457 10 30 10C18.9543 10 10 18.9543 10 30"  stroke="white" stroke-width={cubeWidth}/>
		<path transform={`translate(-20, ${cubeDelta})`} d="M30 50C30 61.0457 38.9543 70 50 70C61.0457 70 70 61.0457 70 50L30 " stroke="white" stroke-width={cubeWidth}/>
	</svg>
	<input type=range min=0 max=20 step=0.01 bind:value={cubeWidth}/>
</div>

<style>
	:global(body) {
		background-color: black;
	}
</style>


Review comment (suggestion):
this fixes: `Form elements do not have associated labels` which TIL it's necessary for a11y.

![CleanShot 2024-01-30 at 21 38 53](https://github.com/unionlabs/union/assets/23618431/553a6372-515a-4b50-a0e5-23903bcc32be)


Code after:
<script lang="ts"> 
	let cubeWidth = 15;
	$: cubeDelta = (20 - cubeWidth) / 2;
</script>

<div class="flex flex-col gap-20 items-center justify-center min-h-screen mx-6">
	<svg width="500px" height="500px" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
		<rect x={60 + cubeDelta } y={30 + cubeDelta} width={cubeWidth} height={cubeWidth} fill="white"/>
		<rect x={40 + cubeDelta} y={30 + cubeDelta} width={cubeWidth} height={cubeWidth} fill="white"/>
		<rect x={20 + cubeDelta} y={30 + cubeDelta} width={cubeWidth} height={cubeWidth} fill="white"/>
		<rect x = {cubeDelta} y={30 + cubeDelta} width={cubeWidth} height={cubeWidth} fill="white"/>
		<path transform={`translate(20, ${-cubeDelta})`} d="M50 30C50 18.9543 41.0457 10 30 10C18.9543 10 10 18.9543 10 30"  stroke="white" stroke-width={cubeWidth}/>
		<path transform={`translate(-20, ${cubeDelta})`} d="M30 50C30 61.0457 38.9543 70 50 70C61.0457 70 70 61.0457 70 50" stroke="white" stroke-width={cubeWidth}/>
	</svg>
	<label class="sr-only" for="range-slider">Thickness range:</label>
	<input id="range-slider" class="w-full max-w-80" type=range min=0 max=20 step=0.01 bind:value={cubeWidth} />
</div>

<style>
	:global(body) {
		background-color: black;
	}
</style>
Repository: unionlabs/union
File: lib/ethereum-verifier/src/lib.rs (Rust)

Code before:
#![feature(assert_matches)]
#![feature(error_in_core)]
extern crate alloc;

mod context;
pub mod crypto;
mod error;
pub mod primitives;
mod rlp_node_codec;
mod serde;
mod utils;
mod verify;

pub use context::*;
pub use error::*;
pub use utils::*;
pub use verify::*;


Review comment (suggestion):
this feature is still quite unstable, i would suggest using `assert!(matches!())`

Code after:
#![feature(error_in_core)]
extern crate alloc;

mod context;
pub mod crypto;
mod error;
pub mod primitives;
mod rlp_node_codec;
mod serde;
mod utils;
mod verify;

pub use context::*;
pub use error::*;
pub use utils::*;
pub use verify::*;
Repository: unionlabs/union
File: lib/pg-queue/migrations/20240316012044_queue.sql (SQL)

Code before:
CREATE TABLE queue (
    id BIGSERIAL,
    status status NOT NULL DEFAULT 'ready',
    item JSONB NOT NULL,
    -- Can't have foreign key relations to hypertables, so recreate the constraints as best as possible
    parent BIGINT DEFAULT NULL CHECK (parent IS NULL OR parent > 0),
    -- Error message in case of permanent failure. If set, status MUST be 'failed'.
    message TEXT CHECK (((message IS NULL) AND (status != 'failed'::status)) OR ((message IS NOT NULL) AND (status = 'failed'::status))),
    created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    PRIMARY KEY (id, created_at)
);

CREATE INDEX index_queue_id ON queue (id);

CREATE INDEX index_queue_status ON queue (status);

CREATE INDEX index_queue_id_status ON queue (id, status);

SELECT create_hypertable('queue', 'created_at');

SELECT add_retention_policy('queue', INTERVAL '60 days');

ALTER TABLE queue SET (timescaledb.compress, timescaledb.compress_orderby = 'created_at DESC', timescaledb.compress_segmentby = 'id');

SELECT add_compression_policy('queue', compress_after => INTERVAL '14 days');


Review comment (suggestion):
we're filtering on `status`, so it should be first

```suggestion
CREATE INDEX index_queue_id_status ON queue (status, id);
```

Code after:
CREATE TABLE queue (
    id BIGSERIAL,
    status status NOT NULL DEFAULT 'ready',
    item JSONB NOT NULL,
    -- Can't have foreign key relations to hypertables, so recreate the constraints as best as possible
    parent BIGINT DEFAULT NULL CHECK (parent IS NULL OR parent > 0),
    -- Error message in case of permanent failure. If set, status MUST be 'failed'.
    message TEXT CHECK (((message IS NULL) AND (status != 'failed'::status)) OR ((message IS NOT NULL) AND (status = 'failed'::status))),
    created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    PRIMARY KEY (id, created_at)
);

CREATE INDEX index_queue_id ON queue (id);

CREATE INDEX index_queue_status_id ON queue (status, id);

SELECT create_hypertable('queue', 'created_at');

SELECT add_retention_policy('queue', INTERVAL '60 days');

ALTER TABLE queue SET (timescaledb.compress, timescaledb.compress_orderby = 'created_at DESC', timescaledb.compress_segmentby = 'id');

SELECT add_compression_policy('queue', compress_after => INTERVAL '14 days');
Repository: unionlabs/union
File: lib/pg-queue/migrations/20240316012044_queue.sql (SQL)

Code before:
CREATE TABLE queue (
    id BIGSERIAL,
    status status NOT NULL DEFAULT 'ready',
    item JSONB NOT NULL,
    -- Can't have foreign key relations to hypertables, so recreate the constraints as best as possible
    parent BIGINT DEFAULT NULL CHECK (parent IS NULL OR parent > 0),
    -- Error message in case of permanent failure. If set, status MUST be 'failed'.
    message TEXT CHECK (((message IS NULL) AND (status != 'failed'::status)) OR ((message IS NOT NULL) AND (status = 'failed'::status))),
    created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    PRIMARY KEY (id, created_at)
);

CREATE INDEX index_queue_id ON queue (id);

CREATE INDEX index_queue_status ON queue (status);

CREATE INDEX index_queue_status_id ON queue (status, id);

SELECT create_hypertable('queue', 'created_at');

SELECT add_retention_policy('queue', INTERVAL '60 days');

ALTER TABLE queue SET (timescaledb.compress, timescaledb.compress_orderby = 'created_at DESC', timescaledb.compress_segmentby = 'id');

SELECT add_compression_policy('queue', compress_after => INTERVAL '14 days');


Review comment (suggestion):
think we don't need this one anymore (because we have one `status` + `id`)

Code after:
CREATE TABLE queue (
    id BIGSERIAL,
    status status NOT NULL DEFAULT 'ready',
    item JSONB NOT NULL,
    -- Can't have foreign key relations to hypertables, so recreate the constraints as best as possible
    parent BIGINT DEFAULT NULL CHECK (parent IS NULL OR parent > 0),
    -- Error message in case of permanent failure. If set, status MUST be 'failed'.
    message TEXT CHECK (((message IS NULL) AND (status != 'failed'::status)) OR ((message IS NOT NULL) AND (status = 'failed'::status))),
    created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
    PRIMARY KEY (id, created_at)
);

CREATE INDEX index_queue_id ON queue (id);

CREATE INDEX index_queue_status_id ON queue (status, id);

SELECT create_hypertable('queue', 'created_at');

SELECT add_retention_policy('queue', INTERVAL '60 days');

ALTER TABLE queue SET (timescaledb.compress, timescaledb.compress_orderby = 'created_at DESC', timescaledb.compress_segmentby = 'id');

SELECT add_compression_policy('queue', compress_after => INTERVAL '14 days');
Repository: unionlabs/union
File: hubble/src/eth/client.rs (Rust)

Code before:
#![allow(clippy::disallowed_types)]
use ethers::{
    core::types::BlockId,
    providers::{Http, Middleware, Provider, ProviderError},
    types::{Block, BlockNumber, TransactionReceipt, TxHash, U256},
};

use crate::tm::client::RaceClient;

impl RaceClient<Provider<Http>> {
    pub async fn get_chainid(&self) -> Result<U256, ProviderError> {
        self.race(|c| c.get_chainid()).await
    }

    pub async fn get_block_receipts<T>(
        &self,
        block: T,
    ) -> Result<Vec<TransactionReceipt>, ProviderError>
    where
        T: Into<BlockNumber> + Send + Sync,
    {
        let block = block.into();
        self.race(|c| c.get_block_receipts(block)).await
    }
    pub async fn get_block<T>(&self, id: T) -> Result<Option<Block<TxHash>>, ProviderError>
    where
        T: Into<BlockId> + Send + Sync,
    {
        let id = id.into();
        self.race(|c| c.get_block(id)).await
    }
}


Review comment (suggestion):
since `RaceClient` is generic over the client implementation, it shouldn't be under the `tm` module but instead in it's own module (`crate::race_client`, for example)

Code after:
#![allow(clippy::disallowed_types)]
use ethers::{
    core::types::BlockId,
    providers::{Http, Middleware, Provider, ProviderError},
    types::{Block, BlockNumber, TransactionReceipt, TxHash, U256},
};

use crate::race_client::RaceClient;

impl RaceClient<Provider<Http>> {
    pub async fn get_chainid(&self) -> Result<U256, ProviderError> {
        self.race(|c| c.get_chainid()).await
    }

    pub async fn get_block_receipts<T>(
        &self,
        block: T,
    ) -> Result<Vec<TransactionReceipt>, ProviderError>
    where
        T: Into<BlockNumber> + Send + Sync,
    {
        let block = block.into();
        self.race(|c| c.get_block_receipts(block)).await
    }
    pub async fn get_block<T>(&self, id: T) -> Result<Option<Block<TxHash>>, ProviderError>
    where
        T: Into<BlockId> + Send + Sync,
    {
        let id = id.into();
        self.race(|c| c.get_block(id)).await
    }
}