-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Anvil RPC tests, introduced generalised interface IEthereumLikeNode a…
…nd common test suite CommonForkNodeWeb3JTest
- Loading branch information
Showing
13 changed files
with
254 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
10 changes: 10 additions & 0 deletions
10
core/src/main/kotlin/vc/rux/pokefork/hardhat/IEthereumLikeNode.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package vc.rux.pokefork.hardhat | ||
|
||
import vc.rux.pokefork.NodeMode | ||
|
||
interface IEthereumLikeNode { | ||
val localRpcNodeUrl: String | ||
|
||
val nodeMode: NodeMode | ||
fun stop() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
18 changes: 18 additions & 0 deletions
18
web3j/src/test/kotlin/vc/rux/pokefork/web3j/AnvilForkWeb3Test.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package vc.rux.pokefork.web3j | ||
|
||
import vc.rux.pokefork.NodeMode | ||
import vc.rux.pokefork.anvil.AnvilNode | ||
import vc.rux.pokefork.anvil.AnvilNodeConfig | ||
|
||
/** | ||
* Since junit5 doesn't support tests with multiple paramterised parameters in constructor and | ||
* inside function body, we have to create a separate class for each test of the implementation. | ||
* | ||
* While this approach works, it reduces readability, so feel free to make PR to address this issue. | ||
*/ | ||
class AnvilForkWeb3Test : CommonForkNodeWeb3JTest() { | ||
override fun forkImplementationFactory(mode: NodeMode): AnvilNode = | ||
AnvilNode.start( | ||
AnvilNodeConfig(nodeMode = mode) | ||
) | ||
} |
173 changes: 173 additions & 0 deletions
173
web3j/src/test/kotlin/vc/rux/pokefork/web3j/CommonForkNodeWeb3JTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
package vc.rux.pokefork.web3j | ||
|
||
import assertk.all | ||
import assertk.assertThat | ||
import assertk.assertions.* | ||
import org.junit.jupiter.api.AfterEach | ||
import org.junit.jupiter.api.Test | ||
import org.junit.jupiter.api.assertThrows | ||
import org.junit.jupiter.params.ParameterizedTest | ||
import org.junit.jupiter.params.provider.CsvSource | ||
import org.web3j.contracts.eip20.generated.ERC20 | ||
import org.web3j.protocol.core.DefaultBlockParameterName.LATEST | ||
import org.web3j.tx.gas.DefaultGasProvider | ||
import vc.rux.pokefork.NodeMode | ||
import vc.rux.pokefork.errors.PokeForkError | ||
import vc.rux.pokefork.hardhat.IEthereumLikeNode | ||
import vc.rux.pokefork.web3j.utils.toHexStringSuffixed | ||
import java.math.BigDecimal | ||
import java.math.BigDecimal.TEN | ||
import java.math.BigInteger | ||
import kotlin.text.RegexOption.IGNORE_CASE | ||
|
||
abstract class CommonForkNodeWeb3JTest { | ||
protected lateinit var fork: IEthereumLikeNode | ||
abstract fun forkImplementationFactory(mode: NodeMode): IEthereumLikeNode | ||
|
||
fun defaultMainnetFork(): IEthereumLikeNode = | ||
forkImplementationFactory(NodeMode.Fork(MAINNET_RPC, 1)) | ||
|
||
@AfterEach | ||
fun afterEach() { | ||
if (::fork.isInitialized) | ||
fork.stop() | ||
} | ||
|
||
@CsvSource(value = ["18100000,0.208933821146944046", "15000000,321495.8128334608039745"]) | ||
@ParameterizedTest(name = "forkBlock changes blocks - blockNumber: {0}, expectedBalance: {1}") | ||
fun `forkBlock changes blocks`(blockNumber: Long, expectedBalance: BigDecimal) { | ||
// given | ||
val fork = defaultMainnetFork() | ||
val web3 = LocalWeb3jNode.from(fork) | ||
|
||
// when | ||
web3.forkBlock(blockNumber) | ||
|
||
// then | ||
assertThat(web3.ethGetBalance(FTX_WALLET, LATEST).send().balance) | ||
.isEqualTo((expectedBalance * TEN.pow(18)).toBigInteger()) | ||
} | ||
|
||
@Test | ||
fun `chainId is set to the required one `() { | ||
// given | ||
fork = forkImplementationFactory(NodeMode.Fork(MAINNET_RPC, 42)) | ||
|
||
// when | ||
val web3 = LocalWeb3jNode.from(fork) | ||
|
||
// then | ||
val chainId = web3.netVersion().send().netVersion | ||
assertThat(chainId).isEqualTo("42") | ||
} | ||
|
||
@Test | ||
fun `when forked, the block number must be greater than 0`() { | ||
// given | ||
fork = defaultMainnetFork() | ||
val web3 = LocalWeb3jNode.from(fork) | ||
|
||
// when and then | ||
assertThat(web3.ethBlockNumber().send().blockNumber.toLong()) | ||
.isGreaterThan(0) | ||
} | ||
|
||
@Test | ||
fun `can mine blocks`() { | ||
// given | ||
fork = defaultMainnetFork() | ||
val web3 = LocalWeb3jNode.from(fork) | ||
val bnBeforeMine = web3.ethBlockNumber().send().blockNumber.toLong() | ||
println(bnBeforeMine) | ||
|
||
// when | ||
web3.mine(42) | ||
|
||
// then | ||
val bnAfterMine = web3.ethBlockNumber().send().blockNumber.toLong() | ||
assertThat(bnAfterMine).isEqualTo(bnBeforeMine + 42) | ||
} | ||
|
||
@Test | ||
fun `setBalance can set balance in forked network`() { | ||
// given | ||
fork = defaultMainnetFork() | ||
val web3 = LocalWeb3jNode.from(fork) | ||
val balanceBefore = web3.ethGetBalance(VITALIK_WALLET, LATEST).send().balance | ||
|
||
// when | ||
web3.setBalance(VITALIK_WALLET, 42.toBigInteger()) | ||
web3.mine(1) | ||
|
||
// then | ||
val balanceAfter = web3.ethGetBalance(VITALIK_WALLET, LATEST).send().balance | ||
assertThat(balanceAfter).all { | ||
println(balanceBefore) | ||
println(balanceAfter) | ||
isNotEqualTo(balanceBefore) | ||
isEqualTo(42.toBigInteger()) | ||
} | ||
} | ||
|
||
|
||
@Test | ||
fun `setStorageAt can change the token name`() { | ||
// given | ||
fork = defaultMainnetFork() | ||
val web3 = LocalWeb3jNode.from(fork) | ||
|
||
val ust = ERC20.load(UST_TOKEN, web3, randomCredentials, DefaultGasProvider()); | ||
val newName = "UnSTablecoin" | ||
val newNameInMemoryLayout = run { // let's do low level string formation | ||
val nameAsHexAlignedLeft = BigInteger(newName.toByteArray()).toHexStringSuffixed(32).drop(2) | ||
BigInteger(nameAsHexAlignedLeft, 16).or(newName.length.toBigInteger() * BigInteger.TWO) | ||
} | ||
// precondition | ||
assertThat(ust.symbol().send()).isEqualTo("UST") | ||
|
||
// when | ||
// utf8 string to BigInteger | ||
web3.setStorageAt(UST_TOKEN, 0x4.toBigInteger(), newNameInMemoryLayout) | ||
|
||
// then | ||
assertThat(ust.symbol().send()).isEqualTo(newName) | ||
} | ||
|
||
@Test | ||
fun `setNextBlockBaseFeePerGas can set base fee per gas`() { | ||
// given | ||
fork = defaultMainnetFork() | ||
val web3 = LocalWeb3jNode.from(fork) | ||
|
||
// when | ||
web3.setNextBlockBaseFeePerGas(42.toBigInteger()) | ||
web3.mine(1) | ||
|
||
// then | ||
val block = web3.ethGetBlockByNumber(LATEST, false).send().block | ||
assertThat(block.baseFeePerGas).isEqualTo(42.toBigInteger()) | ||
} | ||
|
||
@Test | ||
fun `setBalance throws exception if bad params passed`() { | ||
// given | ||
fork = defaultMainnetFork() | ||
val web3 = LocalWeb3jNode.from(fork) | ||
|
||
// when and then | ||
val error = assertThrows<PokeForkError> { | ||
web3.setBalance("0xPoKeForK", 42.toBigInteger()) | ||
} | ||
assertThat(error) | ||
.isInstanceOf<PokeForkRpcCallError>() | ||
.transform { it.error.message } | ||
.containsMatch("(invalid value)|(invalid length)".toRegex(IGNORE_CASE)) // hardhat returns '..invalid value..', anvil - '..invalid length..' | ||
} | ||
|
||
|
||
companion object { | ||
const val VITALIK_WALLET = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" | ||
const val FTX_WALLET = "0x2FAF487A4414Fe77e2327F0bf4AE2a264a776AD2" | ||
const val UST_TOKEN = "0xa47c8bf37f92abed4a126bda807a7b7498661acd" | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
web3j/src/test/kotlin/vc/rux/pokefork/web3j/HardhatForkWeb3Test.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package vc.rux.pokefork.web3j | ||
|
||
import vc.rux.pokefork.NodeMode | ||
import vc.rux.pokefork.hardhat.HardHatNodeConfig | ||
import vc.rux.pokefork.hardhat.HardhatNode | ||
|
||
/** | ||
* Since junit5 doesn't support tests with multiple paramterised parameters in constructor and | ||
* inside function body, we have to create a separate class for each test of the implementation. | ||
* | ||
* While this approach works, it reduces readability, so feel free to make PR to address this issue. | ||
*/ | ||
class HardhatForkWeb3Test : CommonForkNodeWeb3JTest() { | ||
override fun forkImplementationFactory(mode: NodeMode): HardhatNode = | ||
HardhatNode.start( | ||
HardHatNodeConfig(nodeMode = mode) | ||
) | ||
} |
Oops, something went wrong.