hyperledger-web3j / web3j-evm

A library for running an embedded Ethereum EVM in-process on a JVM
https://web3j.io/
Other
66 stars 26 forks source link

Unclear Exception #75

Open azige opened 3 years ago

azige commented 3 years ago

Unclear Exception

Steps To Reproduce

build script

/*
 * This file was generated by the Gradle 'init' task.
 *
 * This generated file contains a sample Kotlin application project to get you started.
 * For more details take a look at the 'Building Java & JVM projects' chapter in the Gradle
 * User Manual available at https://docs.gradle.org/7.1/userguide/building_java_projects.html
 */

plugins {
    // Apply the org.jetbrains.kotlin.jvm Plugin to add support for Kotlin.
    id("org.jetbrains.kotlin.jvm") version "1.5.31"
    id("org.web3j") version "4.8.8"

    // Apply the application plugin to add support for building a CLI application in Java.
    application
}

repositories {
    // Use Maven Central for resolving dependencies.
    mavenCentral()
    maven("https://hyperledger.jfrog.io/artifactory/besu-maven/")
    maven("https://splunk.jfrog.io/splunk/ext-releases-local")
    maven("https://dl.cloudsmith.io/public/consensys/quorum-mainnet-launcher/maven/")
    maven("https://dl.cloudsmith.io/public/consensys/maven/maven/")
}

dependencies {
    // Align versions of all Kotlin components
    implementation(platform("org.jetbrains.kotlin:kotlin-bom"))

    // Use the Kotlin JDK 8 standard library.
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

    // This dependency is used by the application.
    implementation("com.google.guava:guava:30.1-jre")

    // Use the Kotlin JUnit integration.
    testImplementation("org.jetbrains.kotlin:kotlin-test-junit5")

    testImplementation("org.web3j:web3j-unit:4.8.8")
}

solidity {
    version = "0.8.10"
    executable = project.rootDir.toPath().resolve("solc.exe").toAbsolutePath().toString()
}

web3j {
    generatedPackageName = "io.github.azige.ethereum.auction.contracts"
}

tasks.withType<Test> {
    useJUnitPlatform()
}

tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
    kotlinOptions {
        jvmTarget = "11"
    }
}

test code

package io.github.azige.ethereum.auction

import org.junit.jupiter.api.Assertions.*
import org.web3j.EVMTest
import org.web3j.NodeType
import org.web3j.crypto.*
import org.web3j.protocol.Web3j
import org.web3j.tx.TransactionManager
import org.web3j.tx.Transfer
import org.web3j.tx.gas.ContractGasProvider
import org.web3j.utils.Convert
import java.math.BigDecimal
import kotlin.test.*

// Created 2021/11/12 15:24

@EVMTest
internal class AppTest {

    @Test
    fun demo(web3j: Web3j, transactionManager: TransactionManager, gasProvider: ContractGasProvider) {
        val credentials = Credentials.create(Keys.createEcKeyPair())
        Transfer(web3j, transactionManager).sendFunds(credentials.address, BigDecimal.valueOf(100), Convert.Unit.ETHER).send()
    }
}

Expected behavior

Test should end up with a clear exception (there is not enough ether to pay the gas fee)

Actual behavior

Test failed with IllegalArgumentException.

Invalid negative value -1 for scalar encoding
java.lang.IllegalArgumentException: Invalid negative value -1 for scalar encoding
    at com.google.common.base.Preconditions.checkArgument(Preconditions.java:203)
    at org.hyperledger.besu.ethereum.rlp.RLPOutput.writeLongScalar(RLPOutput.java:110)
    at org.hyperledger.besu.ethereum.core.TransactionReceipt.writeToForReceiptTrie(TransactionReceipt.java:198)
    at org.hyperledger.besu.ethereum.mainnet.BodyValidation.lambda$receiptsRoot$2(BodyValidation.java:81)
    at org.hyperledger.besu.ethereum.rlp.RLP.encode(RLP.java:107)
    at org.hyperledger.besu.ethereum.mainnet.BodyValidation.lambda$receiptsRoot$3(BodyValidation.java:80)
    at java.base/java.util.stream.Streams$RangeIntSpliterator.forEachRemaining(Streams.java:104)
    at java.base/java.util.stream.IntPipeline$Head.forEach(IntPipeline.java:593)
    at org.hyperledger.besu.ethereum.mainnet.BodyValidation.receiptsRoot(BodyValidation.java:76)
    at org.web3j.evm.EmbeddedEthereum.processTransaction(EmbeddedEthereum.kt:245)
    at org.web3j.evm.EmbeddedEthereum.processTransaction(EmbeddedEthereum.kt:198)
    at org.web3j.evm.EmbeddedWeb3jService.ethSendRawTransaction(EmbeddedWeb3jService.kt:169)
    at org.web3j.evm.EmbeddedWeb3jService.send(EmbeddedWeb3jService.kt:105)
    at org.web3j.evm.EmbeddedWeb3jService.send(EmbeddedWeb3jService.kt:57)
    at org.web3j.protocol.core.Request.send(Request.java:87)
    at org.web3j.tx.RawTransactionManager.signAndSend(RawTransactionManager.java:195)
    at org.web3j.tx.RawTransactionManager.sendTransaction(RawTransactionManager.java:125)
    at org.web3j.tx.TransactionManager.executeTransaction(TransactionManager.java:80)
    at org.web3j.tx.TransactionManager.executeTransaction(TransactionManager.java:67)
    at org.web3j.tx.ManagedTransaction.send(ManagedTransaction.java:102)
    at org.web3j.tx.Transfer.send(Transfer.java:80)
    at org.web3j.tx.Transfer.send(Transfer.java:56)
    at org.web3j.tx.Transfer.lambda$sendFunds$1(Transfer.java:108)
    at org.web3j.protocol.core.RemoteCall.send(RemoteCall.java:42)
    at io.github.azige.ethereum.auction.AppTest.demo(AppTest.kt:24)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:686)
    at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
    at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
    at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
    at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
    at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:205)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:201)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:137)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:71)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)

Environment

Additional Context

There are logs when using web3j 4.8.4

11:41:28.016 [pool-1-thread-1] WARN org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor - Invalid transaction: transaction up-front cost 100000000000000021000 exceeds transaction sender account balance 10000000000000000000

And the test end up with timeout

org.web3j.protocol.exceptions.TransactionException: Transaction receipt was not generated after 30 seconds for transaction: 0x3ba70c783a4e130fd2f7eaf06682c7f05715928abbbe00d59be2d2aeb3cc1586

I firstly encountered the IllegalArgumentException when deploying a contract. After the investgation I guess it also caused by no enough ether to pay. It may be a web3j-unit related issue (not enough ether in provided account or wrong gas price). I need some suggestions.

azige commented 3 years ago

Here are things I tested. It seems web3j-unit provided account has only 10 ether. Contracts compiled by solc 0.8.10.