diff --git a/build.gradle b/build.gradle index 3a362af..c526b82 100644 --- a/build.gradle +++ b/build.gradle @@ -90,13 +90,15 @@ dependencies { exclude group: "io.netty" exclude group: 'org.fisco-bcos', module: 'tcnative' } - implementation('org.fisco-bcos.java-sdk:fisco-bcos-sdk-abi:2.10.0-SNAPSHOT') + implementation 'org.fisco-bcos.java-sdk:fisco-bcos-sdk-abi:2.10.0-SNAPSHOT' implementation 'org.web3j:core:4.9.8' - // implementation('org.fisco-bcos.java-sdk:fisco-bcos-sdk-abi:2.10.0-SNAPSHOT') - // Use JUnit test framework testImplementation 'junit:junit:4.13.2' + testImplementation 'org.slf4j:slf4j-log4j12:2.0.5' + + integTestImplementation 'junit:junit:4.13.2' + integTestImplementation 'org.slf4j:slf4j-log4j12:2.0.5' } sourceSets { diff --git a/src/main/java/com/webank/wecross/stub/web3/Web3Connection.java b/src/main/java/com/webank/wecross/stub/web3/Web3Connection.java index 5b459e3..7293cf3 100644 --- a/src/main/java/com/webank/wecross/stub/web3/Web3Connection.java +++ b/src/main/java/com/webank/wecross/stub/web3/Web3Connection.java @@ -177,6 +177,13 @@ private void handleAsyncGetBlockNumberRequest(Callback callback) { response.setErrorMessage(Web3StatusCode.getStatusMessage(Web3StatusCode.Success)); try { BigInteger blockNumber = clientWrapper.ethBlockNumber(); + if (Objects.isNull(blockNumber)) { + response.setErrorCode(Web3StatusCode.BlockNumberNotExist); + response.setErrorMessage( + Web3StatusCode.getStatusMessage(Web3StatusCode.BlockNumberNotExist)); + return; + } + if (logger.isDebugEnabled()) { logger.debug("handleAsyncGetBlockNumberRequest,blockNumber: {}", blockNumber); } @@ -211,6 +218,12 @@ private void handleAsyncCallRequest(Request request, Callback callback) { from, to, data); EthCall ethCall = clientWrapper.ethCall(transaction); + if (Objects.isNull(ethCall)) { + response.setErrorCode(Web3StatusCode.CallNotSuccessStatus); + response.setErrorMessage("ethCall is null"); + return; + } + // ethCall has error if (ethCall.hasError()) { response.setErrorCode(Web3StatusCode.CallNotSuccessStatus); @@ -244,6 +257,13 @@ private void handleAsyncTransactionRequest(Request request, Callback callback) { EthSendTransaction ethSendTransaction = clientWrapper.ethSendRawTransaction(signedTransactionData); + if (Objects.isNull(ethSendTransaction)) { + response.setErrorCode(Web3StatusCode.TransactionReceiptNotExist); + response.setErrorMessage( + Web3StatusCode.getStatusMessage(Web3StatusCode.TransactionReceiptNotExist)); + return; + } + // ethSendTransaction has error if (ethSendTransaction.hasError()) { response.setErrorCode(Web3StatusCode.SendTransactionNotSuccessStatus); @@ -253,6 +273,13 @@ private void handleAsyncTransactionRequest(Request request, Callback callback) { // get transactionReceipt String transactionHash = ethSendTransaction.getTransactionHash(); + if (StringUtils.isBlank(transactionHash)) { + response.setErrorCode(Web3StatusCode.TransactionReceiptNotExist); + response.setErrorMessage( + Web3StatusCode.getStatusMessage(Web3StatusCode.TransactionReceiptNotExist)); + return; + } + TransactionReceipt transactionReceipt = clientWrapper.ethGetTransactionReceipt(transactionHash); diff --git a/src/main/java/com/webank/wecross/stub/web3/account/Web3AccountFactory.java b/src/main/java/com/webank/wecross/stub/web3/account/Web3AccountFactory.java index d836af6..ee3a968 100644 --- a/src/main/java/com/webank/wecross/stub/web3/account/Web3AccountFactory.java +++ b/src/main/java/com/webank/wecross/stub/web3/account/Web3AccountFactory.java @@ -3,6 +3,7 @@ import com.webank.wecross.stub.web3.common.Web3Constant; import com.webank.wecross.stub.web3.config.Web3AccountConfig; import com.webank.wecross.stub.web3.config.Web3AccountConfigParser; +import java.io.File; import java.io.IOException; import java.util.Map; import java.util.Objects; @@ -67,6 +68,8 @@ public static Web3Account build(Map properties) { // build credentials from privateKey Credentials credentials = Credentials.create(secKey); Web3Account web3Account = new Web3Account(username, type, credentials); + web3Account.setDefault(isDefault); + web3Account.setKeyID(keyID); // check publicKey if (!Objects.equals(web3Account.getPublicKey(), pubKey)) { @@ -84,7 +87,8 @@ public static Web3Account build(Map properties) { } } - public Web3Account build(String name, String accountPath) throws IOException, CipherException { + public static Web3Account build(String name, String accountPath) + throws IOException, CipherException { Web3AccountConfigParser parser = new Web3AccountConfigParser(accountPath, Web3Constant.ACCOUNT_TOML_NAME); Web3AccountConfig web3AccountConfig = parser.loadConfig(); @@ -94,7 +98,7 @@ public Web3Account build(String name, String accountPath) throws IOException, Ci String password = account.getPassword(); ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); - Resource accountFileResource = resolver.getResource(accountFile); + Resource accountFileResource = resolver.getResource(accountPath + File.separator + accountFile); Credentials credentials; diff --git a/src/main/java/com/webank/wecross/stub/web3/client/ClientWrapper.java b/src/main/java/com/webank/wecross/stub/web3/client/ClientWrapper.java index 45e3e59..819c1d0 100644 --- a/src/main/java/com/webank/wecross/stub/web3/client/ClientWrapper.java +++ b/src/main/java/com/webank/wecross/stub/web3/client/ClientWrapper.java @@ -2,9 +2,12 @@ import java.io.IOException; import java.math.BigInteger; +import org.reactivestreams.Subscriber; +import org.web3j.protocol.core.methods.request.EthFilter; import org.web3j.protocol.core.methods.response.EthBlock; import org.web3j.protocol.core.methods.response.EthCall; import org.web3j.protocol.core.methods.response.EthSendTransaction; +import org.web3j.protocol.core.methods.response.Log; import org.web3j.protocol.core.methods.response.Transaction; import org.web3j.protocol.core.methods.response.TransactionReceipt; @@ -31,4 +34,6 @@ EthCall ethCall(org.web3j.protocol.core.methods.request.Transaction transaction) BigInteger ethGasPrice() throws IOException; BigInteger ethGasLimit() throws IOException; + + void subscribe(EthFilter ethFilter, Subscriber subscriber); } diff --git a/src/main/java/com/webank/wecross/stub/web3/client/ClientWrapperImpl.java b/src/main/java/com/webank/wecross/stub/web3/client/ClientWrapperImpl.java index fc7cb72..f993647 100644 --- a/src/main/java/com/webank/wecross/stub/web3/client/ClientWrapperImpl.java +++ b/src/main/java/com/webank/wecross/stub/web3/client/ClientWrapperImpl.java @@ -5,16 +5,19 @@ import java.math.BigInteger; import java.util.Objects; import java.util.Optional; +import org.reactivestreams.Subscriber; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.web3j.protocol.Web3j; import org.web3j.protocol.core.DefaultBlockParameter; import org.web3j.protocol.core.DefaultBlockParameterName; +import org.web3j.protocol.core.methods.request.EthFilter; import org.web3j.protocol.core.methods.response.EthBlock; import org.web3j.protocol.core.methods.response.EthCall; import org.web3j.protocol.core.methods.response.EthGetTransactionCount; import org.web3j.protocol.core.methods.response.EthGetTransactionReceipt; import org.web3j.protocol.core.methods.response.EthSendTransaction; +import org.web3j.protocol.core.methods.response.Log; import org.web3j.protocol.core.methods.response.Transaction; import org.web3j.protocol.core.methods.response.TransactionReceipt; import org.web3j.utils.RevertReasonExtractor; @@ -119,6 +122,11 @@ public BigInteger ethGasLimit() throws IOException { return web3j.ethMaxPriorityFeePerGas().send().getMaxPriorityFeePerGas(); } + @Override + public void subscribe(EthFilter ethFilter, Subscriber subscriber) { + web3j.ethLogFlowable(ethFilter).safeSubscribe(subscriber); + } + public String extractRevertReason(TransactionReceipt transactionReceipt, String data) throws IOException { String revertReason = diff --git a/src/main/java/com/webank/wecross/stub/web3/common/Web3StatusCode.java b/src/main/java/com/webank/wecross/stub/web3/common/Web3StatusCode.java index 267af13..a3cf92f 100644 --- a/src/main/java/com/webank/wecross/stub/web3/common/Web3StatusCode.java +++ b/src/main/java/com/webank/wecross/stub/web3/common/Web3StatusCode.java @@ -13,16 +13,14 @@ public class Web3StatusCode { public static final int TransactionReceiptNotExist = 2010; public static final int TransactionNotExist = 2011; public static final int BlockNotExist = 2012; - public static final int TransactionProofNotExist = 2013; - public static final int TransactionReceiptProofNotExist = 2014; + public static final int BlockNumberNotExist = 2013; public static final int HandleSendTransactionFailed = 2021; public static final int HandleCallRequestFailed = 2022; public static final int HandleGetBlockNumberFailed = 2023; public static final int HandleGetBlockFailed = 2024; public static final int HandleGetTransactionFailed = 2025; - public static final int ListResourcesFailed = 2026; - public static final int RegisterContractFailed = 2027; + public static final int RegisterContractFailed = 2026; public static final int CallNotSuccessStatus = 2030; public static final int SendTransactionNotSuccessStatus = 2031; @@ -64,11 +62,8 @@ public static String getStatusMessage(int status) { case TransactionNotExist: message = "transaction not exist"; break; - case TransactionProofNotExist: - message = "transaction proof not exist"; - break; - case TransactionReceiptProofNotExist: - message = "transaction receipt proof not exist"; + case BlockNumberNotExist: + message = "block number not exist"; break; case BlockNotExist: message = "block not exist"; diff --git a/src/main/java/com/webank/wecross/stub/web3/config/Web3StubConfig.java b/src/main/java/com/webank/wecross/stub/web3/config/Web3StubConfig.java index 44a746b..f2b272b 100644 --- a/src/main/java/com/webank/wecross/stub/web3/config/Web3StubConfig.java +++ b/src/main/java/com/webank/wecross/stub/web3/config/Web3StubConfig.java @@ -23,6 +23,7 @@ public List convertToResourceInfos() { resourceInfo.setStubType(this.getCommon().getType()); Map properties = resourceInfo.getProperties(); + properties.put(Web3Constant.WEB3_PROPERTY_CHAIN_URL, this.getService().getUrl()); properties.put(resource.getName(), resource.getAddress()); properties.put(resource.getName() + Web3Constant.WEB3_PROPERTY_ABI_SUFFIX, resource.getAbi()); resourceInfos.add(resourceInfo); diff --git a/src/main/java/com/webank/wecross/stub/web3/event/Web3ChainEventManager.java b/src/main/java/com/webank/wecross/stub/web3/event/Web3ChainEventManager.java new file mode 100644 index 0000000..d2d30e1 --- /dev/null +++ b/src/main/java/com/webank/wecross/stub/web3/event/Web3ChainEventManager.java @@ -0,0 +1,92 @@ +package com.webank.wecross.stub.web3.event; + +import com.webank.wecross.stub.web3.client.ClientWrapper; +import com.webank.wecross.stub.web3.config.Web3StubConfig; +import java.util.Arrays; +import org.reactivestreams.Subscriber; +import org.reactivestreams.Subscription; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.web3j.abi.EventEncoder; +import org.web3j.abi.TypeReference; +import org.web3j.abi.datatypes.Address; +import org.web3j.abi.datatypes.DynamicArray; +import org.web3j.abi.datatypes.Event; +import org.web3j.abi.datatypes.Utf8String; +import org.web3j.abi.datatypes.generated.Uint256; +import org.web3j.protocol.core.DefaultBlockParameterName; +import org.web3j.protocol.core.methods.request.EthFilter; +import org.web3j.protocol.core.methods.response.Log; + +public class Web3ChainEventManager { + private static final Logger logger = LoggerFactory.getLogger(Web3ChainEventManager.class); + + private final ClientWrapper clientWrapper; + + public static final String LUYU_CALL = "LuyuCall"; + public static final String LUYU_SEND_TRANSACTION = "LuyuSendTransaction"; + + public static final Event LUYUCALL_EVENT = + new Event( + LUYU_CALL, + Arrays.asList( + new TypeReference() {}, + new TypeReference() {}, + new TypeReference>() {}, + new TypeReference() {}, + new TypeReference() {}, + new TypeReference() {}, + new TypeReference
() {})); + + public static final Event LUYUSENDTRANSACTION_EVENT = + new Event( + LUYU_SEND_TRANSACTION, + Arrays.asList( + new TypeReference() {}, + new TypeReference() {}, + new TypeReference>() {}, + new TypeReference() {}, + new TypeReference() {}, + new TypeReference() {}, + new TypeReference
() {})); + + public Web3ChainEventManager(ClientWrapper clientWrapper) { + this.clientWrapper = clientWrapper; + } + + public void registerEvent(Web3StubConfig.Resource resource) { + registerEvent(resource.getName(), resource.getAddress(), LUYUCALL_EVENT); + registerEvent(resource.getName(), resource.getAddress(), LUYUSENDTRANSACTION_EVENT); + } + + private void registerEvent(String resourceName, String address, Event event) { + EthFilter ethFilter = + new EthFilter( + DefaultBlockParameterName.EARLIEST, DefaultBlockParameterName.LATEST, address); + String encodedEventSignature = EventEncoder.encode(event); + ethFilter.addSingleTopic(encodedEventSignature); + + clientWrapper.subscribe( + ethFilter, + new Subscriber() { + @Override + public void onSubscribe(Subscription subscription) { + subscription.request(Long.MAX_VALUE); + } + + @Override + public void onNext(Log log) { + // TODO handle events based on event name + String eventName = event.getName(); + } + + @Override + public void onError(Throwable throwable) {} + + @Override + public void onComplete() { + registerEvent(resourceName, address, event); + } + }); + } +} diff --git a/src/test/java/com/webank/wecross/stub/web3/Web3AccountFactoryTest.java b/src/test/java/com/webank/wecross/stub/web3/Web3AccountFactoryTest.java new file mode 100644 index 0000000..9dd4e04 --- /dev/null +++ b/src/test/java/com/webank/wecross/stub/web3/Web3AccountFactoryTest.java @@ -0,0 +1,27 @@ +package com.webank.wecross.stub.web3; + +import static junit.framework.TestCase.assertEquals; +import static junit.framework.TestCase.assertTrue; + +import com.webank.wecross.stub.web3.account.Web3Account; +import com.webank.wecross.stub.web3.account.Web3AccountFactory; +import java.io.IOException; +import java.util.Objects; +import org.junit.Test; +import org.web3j.crypto.CipherException; + +public class Web3AccountFactoryTest { + + @Test + public void buildAccountTest() throws CipherException, IOException { + Web3Account web3Account = Web3AccountFactory.build("wallet", "./account"); + + assertTrue(Objects.nonNull(web3Account)); + assertEquals(web3Account.getName(), "wallet"); + assertEquals(web3Account.getType(), "WEB3"); + assertEquals(web3Account.getIdentity(), "0x698d83382f9ffb72271cd0826479e8ab02077842"); + assertEquals( + web3Account.getPublicKey(), + "ab1c9d486b269adbb604766daf7d209440663299dd78b229ffcf728568b6b8a93c8a096ca4328d93040a0c8b4bd448e0e2da2566bf252845426f806a053d2cc6"); + } +} diff --git a/src/test/java/com/webank/wecross/stub/web3/Web3ConnectionFailedTest.java b/src/test/java/com/webank/wecross/stub/web3/Web3ConnectionFailedTest.java new file mode 100644 index 0000000..43c809b --- /dev/null +++ b/src/test/java/com/webank/wecross/stub/web3/Web3ConnectionFailedTest.java @@ -0,0 +1,314 @@ +package com.webank.wecross.stub.web3; + +import static junit.framework.TestCase.assertEquals; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.webank.wecross.stub.Request; +import com.webank.wecross.stub.TransactionRequest; +import com.webank.wecross.stub.web3.client.ClientWrapper; +import com.webank.wecross.stub.web3.client.ClientWrapperNotSuccessStatus; +import com.webank.wecross.stub.web3.client.ClientWrapperWithExceptionMock; +import com.webank.wecross.stub.web3.client.ClientWrapperWithNullMock; +import com.webank.wecross.stub.web3.common.Web3RequestType; +import com.webank.wecross.stub.web3.common.Web3StatusCode; +import com.webank.wecross.stub.web3.protocol.request.TransactionParams; +import java.io.IOException; +import java.math.BigInteger; +import java.util.Arrays; +import java.util.Collections; +import org.junit.Before; +import org.junit.Test; +import org.web3j.abi.FunctionEncoder; +import org.web3j.abi.TypeReference; +import org.web3j.abi.datatypes.Function; +import org.web3j.abi.datatypes.Utf8String; +import org.web3j.crypto.Credentials; +import org.web3j.crypto.RawTransaction; +import org.web3j.crypto.TransactionEncoder; +import org.web3j.protocol.ObjectMapperFactory; +import org.web3j.utils.Numeric; + +public class Web3ConnectionFailedTest { + private final ObjectMapper objectMapper = ObjectMapperFactory.getObjectMapper(); + + @Before + public void init() { + this.objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS); + } + + @Test + public void handleExceptionGetBlockNumberTest() throws IOException { + ClientWrapper clientWrapper = new ClientWrapperWithExceptionMock(); + Web3Connection web3Connection = new Web3Connection(clientWrapper, "./stub-sample.toml"); + Request request = new Request(); + request.setType(Web3RequestType.GET_BLOCK_NUMBER); + web3Connection.asyncSend( + request, + response -> { + assertEquals(response.getErrorCode(), Web3StatusCode.HandleGetBlockNumberFailed); + }); + } + + @Test + public void handleNullGetBlockNumberTest() throws IOException { + ClientWrapper clientWrapper = new ClientWrapperWithNullMock(); + Web3Connection web3Connection = new Web3Connection(clientWrapper, "./stub-sample.toml"); + Request request = new Request(); + request.setType(Web3RequestType.GET_BLOCK_NUMBER); + web3Connection.asyncSend( + request, + response -> { + assertEquals(response.getErrorCode(), Web3StatusCode.BlockNumberNotExist); + }); + } + + @Test + public void handleExceptionGetBlockTest() throws IOException { + ClientWrapper clientWrapper = new ClientWrapperWithExceptionMock(); + Web3Connection web3Connection = new Web3Connection(clientWrapper, "./stub-sample.toml"); + Request request = new Request(); + request.setType(Web3RequestType.GET_BLOCK_BY_NUMBER); + request.setData(BigInteger.valueOf(108214).toByteArray()); + web3Connection.asyncSend( + request, + response -> { + assertEquals(response.getErrorCode(), Web3StatusCode.HandleGetBlockFailed); + }); + } + + @Test + public void handleNullGetBlockTest() throws IOException { + ClientWrapper clientWrapper = new ClientWrapperWithNullMock(); + Web3Connection web3Connection = new Web3Connection(clientWrapper, "./stub-sample.toml"); + Request request = new Request(); + request.setType(Web3RequestType.GET_BLOCK_BY_NUMBER); + request.setData(BigInteger.valueOf(108214).toByteArray()); + web3Connection.asyncSend( + request, + response -> { + assertEquals(response.getErrorCode(), Web3StatusCode.BlockNotExist); + }); + } + + @Test + public void handleExceptionGetTransactionTest() throws IOException { + ClientWrapper clientWrapper = new ClientWrapperWithExceptionMock(); + Web3Connection web3Connection = new Web3Connection(clientWrapper, "./stub-sample.toml"); + String transactionHash = "0x4980adef7b9a6d2cd709cdbd1f308ddff18c6486b3a06fd85387450a87bce8c4"; + Request request = new Request(); + request.setType(Web3RequestType.GET_TRANSACTION); + request.setData(transactionHash.getBytes()); + web3Connection.asyncSend( + request, + response -> { + assertEquals(response.getErrorCode(), Web3StatusCode.HandleGetTransactionFailed); + }); + } + + @Test + public void handleNullGetTransactionTest() throws IOException { + ClientWrapper clientWrapper = new ClientWrapperWithNullMock(); + Web3Connection web3Connection = new Web3Connection(clientWrapper, "./stub-sample.toml"); + String transactionHash = "0x4980adef7b9a6d2cd709cdbd1f308ddff18c6486b3a06fd85387450a87bce8c4"; + Request request = new Request(); + request.setType(Web3RequestType.GET_TRANSACTION); + request.setData(transactionHash.getBytes()); + web3Connection.asyncSend( + request, + response -> { + assertEquals(response.getErrorCode(), Web3StatusCode.TransactionNotExist); + }); + } + + @Test + public void handleExceptionCallTest() throws IOException { + ClientWrapper clientWrapper = new ClientWrapperWithExceptionMock(); + Web3Connection web3Connection = new Web3Connection(clientWrapper, "./stub-sample.toml"); + + String method = "get"; + String[] params = new String[] {}; + TransactionRequest transactionRequest = new TransactionRequest(method, params); + + Function function = + new Function( + method, Collections.emptyList(), Arrays.asList(new TypeReference() {})); + String from = "0xaff0ca253b97e54440965855cec0a8a2e2399896"; + String to = "0x7cf92bd66acacf18f46a4e2dc0280cd67bfae923"; + String data = FunctionEncoder.encode(function); + String abi = + "[{\"constant\":false,\"inputs\":[{\"name\":\"n\",\"type\":\"string\"}],\"name\":\"set\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"get\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}]"; + TransactionParams transactionParams = + new TransactionParams( + transactionRequest, TransactionParams.SUB_TYPE.CALL, from, to, data, abi); + + Request request = new Request(); + request.setType(Web3RequestType.CALL); + request.setData(ObjectMapperFactory.getObjectMapper().writeValueAsBytes(transactionParams)); + + web3Connection.asyncSend( + request, + response -> { + assertEquals(response.getErrorCode(), Web3StatusCode.HandleCallRequestFailed); + }); + } + + @Test + public void handleNullCallTest() throws IOException { + ClientWrapper clientWrapper = new ClientWrapperWithNullMock(); + Web3Connection web3Connection = new Web3Connection(clientWrapper, "./stub-sample.toml"); + + String method = "get"; + String[] params = new String[] {}; + TransactionRequest transactionRequest = new TransactionRequest(method, params); + + Function function = + new Function( + method, Collections.emptyList(), Arrays.asList(new TypeReference() {})); + String from = "0xaff0ca253b97e54440965855cec0a8a2e2399896"; + String to = "0x7cf92bd66acacf18f46a4e2dc0280cd67bfae923"; + String data = FunctionEncoder.encode(function); + String abi = + "[{\"constant\":false,\"inputs\":[{\"name\":\"n\",\"type\":\"string\"}],\"name\":\"set\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"get\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}]"; + TransactionParams transactionParams = + new TransactionParams( + transactionRequest, TransactionParams.SUB_TYPE.CALL, from, to, data, abi); + + Request request = new Request(); + request.setType(Web3RequestType.CALL); + request.setData(ObjectMapperFactory.getObjectMapper().writeValueAsBytes(transactionParams)); + + web3Connection.asyncSend( + request, + response -> { + assertEquals(response.getErrorCode(), Web3StatusCode.CallNotSuccessStatus); + }); + } + + @Test + public void handleNotSuccessCallTest() throws IOException { + ClientWrapper clientWrapper = new ClientWrapperNotSuccessStatus(); + Web3Connection web3Connection = new Web3Connection(clientWrapper, "./stub-sample.toml"); + + String method = "get"; + String[] params = new String[] {}; + TransactionRequest transactionRequest = new TransactionRequest(method, params); + + Function function = + new Function( + method, Collections.emptyList(), Arrays.asList(new TypeReference() {})); + String from = "0xaff0ca253b97e54440965855cec0a8a2e2399896"; + String to = "0x7cf92bd66acacf18f46a4e2dc0280cd67bfae923"; + String data = FunctionEncoder.encode(function); + String abi = + "[{\"constant\":false,\"inputs\":[{\"name\":\"n\",\"type\":\"string\"}],\"name\":\"set\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"get\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}]"; + TransactionParams transactionParams = + new TransactionParams( + transactionRequest, TransactionParams.SUB_TYPE.CALL, from, to, data, abi); + + Request request = new Request(); + request.setType(Web3RequestType.CALL); + request.setData(ObjectMapperFactory.getObjectMapper().writeValueAsBytes(transactionParams)); + + web3Connection.asyncSend( + request, + response -> { + assertEquals(response.getErrorCode(), Web3StatusCode.CallNotSuccessStatus); + assertEquals(response.getErrorMessage(), "execution reverted: method reverted!"); + }); + } + + @Test + public void handleExceptionSendTransactionTest() throws IOException { + ClientWrapper clientWrapper = new ClientWrapperWithExceptionMock(); + Web3Connection web3Connection = new Web3Connection(clientWrapper, "./stub-sample.toml"); + + String method = "set"; + String[] params = new String[] {"hello world!!!"}; + TransactionRequest transactionRequest = new TransactionRequest(method, params); + Function function = + new Function( + method, Arrays.asList(new Utf8String("hello world!!!")), Collections.emptyList()); + String data = FunctionEncoder.encode(function); + + String privateKey = "4b9f63ecf84210c5366c66d68fa1f5da1fa4f634fad6dfc86178e4d79ff9e59"; + Credentials credentials = Credentials.create(privateKey); + RawTransaction rawTransaction = + RawTransaction.createTransaction( + clientWrapper.getNonce(credentials.getAddress()), + clientWrapper.ethGasPrice(), + clientWrapper.ethGasLimit(), + "0x7cf92bd66acacf18f46a4e2dc0280cd67bfae923", + data); + + byte[] signedMessage = + TransactionEncoder.signMessage( + rawTransaction, clientWrapper.ethChainId().longValue(), credentials); + String abi = + "[{\"constant\":false,\"inputs\":[{\"name\":\"n\",\"type\":\"string\"}],\"name\":\"set\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"get\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}]"; + + TransactionParams transactionParams = + new TransactionParams( + transactionRequest, + TransactionParams.SUB_TYPE.SEND_TX, + Numeric.toHexString(signedMessage), + abi); + + Request request = new Request(); + request.setType(Web3RequestType.SEND_TRANSACTION); + request.setData(ObjectMapperFactory.getObjectMapper().writeValueAsBytes(transactionParams)); + + web3Connection.asyncSend( + request, + response -> { + assertEquals(response.getErrorCode(), Web3StatusCode.HandleSendTransactionFailed); + }); + } + + @Test + public void handleNullSendTransactionTest() throws IOException { + ClientWrapper clientWrapper = new ClientWrapperWithNullMock(); + Web3Connection web3Connection = new Web3Connection(clientWrapper, "./stub-sample.toml"); + + String method = "set"; + String[] params = new String[] {"hello world!!!"}; + TransactionRequest transactionRequest = new TransactionRequest(method, params); + Function function = + new Function( + method, Arrays.asList(new Utf8String("hello world!!!")), Collections.emptyList()); + String data = FunctionEncoder.encode(function); + + String privateKey = "4b9f63ecf84210c5366c66d68fa1f5da1fa4f634fad6dfc86178e4d79ff9e59"; + Credentials credentials = Credentials.create(privateKey); + RawTransaction rawTransaction = + RawTransaction.createTransaction( + clientWrapper.getNonce(credentials.getAddress()), + clientWrapper.ethGasPrice(), + clientWrapper.ethGasLimit(), + "0x7cf92bd66acacf18f46a4e2dc0280cd67bfae923", + data); + + byte[] signedMessage = + TransactionEncoder.signMessage( + rawTransaction, clientWrapper.ethChainId().longValue(), credentials); + String abi = + "[{\"constant\":false,\"inputs\":[{\"name\":\"n\",\"type\":\"string\"}],\"name\":\"set\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"get\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}]"; + + TransactionParams transactionParams = + new TransactionParams( + transactionRequest, + TransactionParams.SUB_TYPE.SEND_TX, + Numeric.toHexString(signedMessage), + abi); + + Request request = new Request(); + request.setType(Web3RequestType.SEND_TRANSACTION); + request.setData(ObjectMapperFactory.getObjectMapper().writeValueAsBytes(transactionParams)); + + web3Connection.asyncSend( + request, + response -> { + assertEquals(response.getErrorCode(), Web3StatusCode.TransactionReceiptNotExist); + }); + } +} diff --git a/src/test/java/com/webank/wecross/stub/web3/Web3ConnectionTest.java b/src/test/java/com/webank/wecross/stub/web3/Web3ConnectionTest.java new file mode 100644 index 0000000..b67c7d8 --- /dev/null +++ b/src/test/java/com/webank/wecross/stub/web3/Web3ConnectionTest.java @@ -0,0 +1,282 @@ +package com.webank.wecross.stub.web3; + +import static junit.framework.TestCase.assertEquals; +import static junit.framework.TestCase.assertFalse; +import static junit.framework.TestCase.assertTrue; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.webank.wecross.stub.Block; +import com.webank.wecross.stub.BlockHeader; +import com.webank.wecross.stub.Request; +import com.webank.wecross.stub.ResourceInfo; +import com.webank.wecross.stub.TransactionRequest; +import com.webank.wecross.stub.web3.client.ClientWrapper; +import com.webank.wecross.stub.web3.client.ClientWrapperImplMock; +import com.webank.wecross.stub.web3.common.Web3Constant; +import com.webank.wecross.stub.web3.common.Web3RequestType; +import com.webank.wecross.stub.web3.common.Web3StatusCode; +import com.webank.wecross.stub.web3.config.Web3StubConfig; +import com.webank.wecross.stub.web3.config.Web3StubConfigParser; +import com.webank.wecross.stub.web3.contract.BlockUtility; +import com.webank.wecross.stub.web3.protocol.request.TransactionParams; +import com.webank.wecross.stub.web3.protocol.response.TransactionPair; +import java.io.IOException; +import java.math.BigInteger; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import org.junit.Before; +import org.junit.Test; +import org.web3j.abi.FunctionEncoder; +import org.web3j.abi.TypeReference; +import org.web3j.abi.datatypes.Function; +import org.web3j.abi.datatypes.Utf8String; +import org.web3j.crypto.Credentials; +import org.web3j.crypto.RawTransaction; +import org.web3j.crypto.TransactionEncoder; +import org.web3j.protocol.ObjectMapperFactory; +import org.web3j.protocol.core.methods.response.EthBlock; +import org.web3j.protocol.core.methods.response.EthCall; +import org.web3j.protocol.core.methods.response.Transaction; +import org.web3j.protocol.core.methods.response.TransactionReceipt; +import org.web3j.utils.Numeric; + +public class Web3ConnectionTest { + private final ObjectMapper objectMapper = ObjectMapperFactory.getObjectMapper(); + private Web3Connection web3Connection; + + @Before + public void init() throws IOException { + this.objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS); + ClientWrapper clientWrapper = new ClientWrapperImplMock(); + this.web3Connection = new Web3Connection(clientWrapper, "./stub-sample.toml"); + } + + @Test + public void toBlockHeaderTest() throws IOException { + String blockJson = + "{\"number\":108214,\"hash\":\"0x8abe7ca191df7a3b0cc3f081d6d5a1bd2d542bb6a6b7a5c6a9e75244d90c5aad\",\"parentHash\":\"0x21a26483f5968cdaecfc8a85bd92fda6692ceee52b6716dd2c8fa65225820496\",\"nonce\":0,\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"transactionsRoot\":\"0xe7acf5d55d7d2e63d7c0989660a72cf099539be3abe06a446b1db73b3ff5adf4\",\"stateRoot\":\"0x2473e460d2818392c43f5775203c160d23fa13774b82798687cf99e3db7ec054\",\"receiptsRoot\":\"0x3998b0b006ea68156060551908975d78935a9add49a23f65ce497af6a5be311e\",\"author\":null,\"miner\":\"0x8943545177806ed17b9f23f0a21ee5948ecaa776\",\"mixHash\":\"0x928fe08f6690213632620d84bae3826710c959bf9f079001a75c6ff537932c19\",\"difficulty\":0,\"totalDifficulty\":1,\"extraData\":\"0xd883010e07846765746888676f312e32322e35856c696e7578\",\"size\":816,\"gasLimit\":30000000,\"gasUsed\":24780,\"timestamp\":1723105141,\"transactions\":[{\"hash\":\"0x4980adef7b9a6d2cd709cdbd1f308ddff18c6486b3a06fd85387450a87bce8c4\",\"nonce\":77,\"blockHash\":\"0x8abe7ca191df7a3b0cc3f081d6d5a1bd2d542bb6a6b7a5c6a9e75244d90c5aad\",\"blockNumber\":108214,\"chainId\":1337,\"transactionIndex\":0,\"from\":\"0xaff0ca253b97e54440965855cec0a8a2e2399896\",\"to\":\"0x7cf92bd66acacf18f46a4e2dc0280cd67bfae923\",\"value\":0,\"gasPrice\":22000000000,\"gas\":4300000,\"input\":\"0x4ed3885e0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000e78697869786978692121217e7e7e000000000000000000000000000000000000\",\"creates\":null,\"publicKey\":null,\"raw\":null,\"r\":\"0x4e608162ddfc7e43284df9d8d6e40b151b116fcb0f7c14690c0a92ead1214c30\",\"s\":\"0x49789a1f93f74ef1060048a5871604c4419650ced2ab37786094f2cdd5677224\",\"v\":2710,\"type\":\"0x0\",\"maxFeePerGas\":null,\"maxPriorityFeePerGas\":null,\"accessList\":null,\"transactionIndexRaw\":\"0x0\",\"blockNumberRaw\":\"0x1a6b6\",\"maxPriorityFeePerGasRaw\":null,\"gasPriceRaw\":\"0x51f4d5c00\",\"nonceRaw\":\"0x4d\",\"gasRaw\":\"0x419ce0\",\"valueRaw\":\"0x0\",\"chainIdRaw\":\"0x539\",\"maxFeePerGasRaw\":null}],\"uncles\":[],\"sealFields\":null,\"baseFeePerGas\":7,\"gasUsedRaw\":\"0x60cc\",\"nonceRaw\":\"0x0000000000000000\",\"difficultyRaw\":\"0x0\",\"sizeRaw\":\"0x330\",\"numberRaw\":\"0x1a6b6\",\"gasLimitRaw\":\"0x1c9c380\",\"timestampRaw\":\"0x66b47f75\",\"totalDifficultyRaw\":\"0x1\",\"baseFeePerGasRaw\":\"0x7\"}"; + EthBlock.Block block = objectMapper.readValue(blockJson, EthBlock.Block.class); + BlockHeader blockHeader = BlockUtility.convertToBlockHeader(block); + + assertEquals(blockHeader.getNumber(), block.getNumber().longValue()); + assertEquals(blockHeader.getPrevHash(), block.getParentHash()); + assertEquals(blockHeader.getHash(), block.getHash()); + assertEquals(blockHeader.getStateRoot(), block.getStateRoot()); + assertEquals(blockHeader.getTransactionRoot(), block.getTransactionsRoot()); + assertEquals(blockHeader.getReceiptRoot(), block.getReceiptsRoot()); + assertEquals(blockHeader.getTimestamp(), block.getTimestamp().longValue()); + } + + @Test + public void resourceInfoListTest() throws IOException { + Web3StubConfigParser web3StubConfigParser = new Web3StubConfigParser("./", "stub-sample.toml"); + Web3StubConfig web3StubConfig = web3StubConfigParser.loadConfig(); + List resourceInfoList = web3StubConfig.convertToResourceInfos(); + + assertEquals(resourceInfoList.size(), web3StubConfig.getResources().size()); + + for (ResourceInfo resourceInfo : resourceInfoList) { + assertEquals(resourceInfo.getStubType(), web3StubConfig.getCommon().getType()); + assertEquals( + resourceInfo.getProperties().get(Web3Constant.WEB3_PROPERTY_CHAIN_URL), + web3StubConfig.getService().getUrl()); + } + } + + @Test + public void handleUnknownTypeTest() { + Request request = new Request(); + request.setType(2000); + web3Connection.asyncSend( + request, + response -> { + assertEquals(response.getErrorCode(), Web3StatusCode.UnrecognizedRequestType); + }); + } + + @Test + public void handleGetBlockNumberTest() { + Request request = new Request(); + request.setType(Web3RequestType.GET_BLOCK_NUMBER); + web3Connection.asyncSend( + request, + response -> { + assertEquals(response.getErrorCode(), Web3StatusCode.Success); + + BigInteger blockNumber = new BigInteger(response.getData()); + assertEquals(blockNumber.longValue(), 108214); + }); + } + + @Test + public void handleGetBlockTest() { + Request request = new Request(); + request.setType(Web3RequestType.GET_BLOCK_BY_NUMBER); + request.setData(BigInteger.valueOf(108214).toByteArray()); + web3Connection.asyncSend( + request, + response -> { + assertEquals(response.getErrorCode(), Web3StatusCode.Success); + + Block block = null; + try { + block = BlockUtility.convertToBlock(response.getData(), false); + } catch (IOException e) { + e.printStackTrace(); + } + assertTrue(Objects.nonNull(block)); + + BlockHeader blockHeader = block.getBlockHeader(); + assertEquals(blockHeader.getNumber(), 108214); + assertEquals( + blockHeader.getPrevHash(), + "0x21a26483f5968cdaecfc8a85bd92fda6692ceee52b6716dd2c8fa65225820496"); + assertEquals( + blockHeader.getHash(), + "0x8abe7ca191df7a3b0cc3f081d6d5a1bd2d542bb6a6b7a5c6a9e75244d90c5aad"); + assertEquals( + blockHeader.getStateRoot(), + "0x2473e460d2818392c43f5775203c160d23fa13774b82798687cf99e3db7ec054"); + assertEquals( + blockHeader.getTransactionRoot(), + "0xe7acf5d55d7d2e63d7c0989660a72cf099539be3abe06a446b1db73b3ff5adf4"); + assertEquals( + blockHeader.getReceiptRoot(), + "0x3998b0b006ea68156060551908975d78935a9add49a23f65ce497af6a5be311e"); + assertEquals(blockHeader.getTimestamp(), 1723105141); + }); + } + + @Test + public void handleGetTransactionTest() { + String transactionHash = "0x4980adef7b9a6d2cd709cdbd1f308ddff18c6486b3a06fd85387450a87bce8c4"; + Request request = new Request(); + request.setType(Web3RequestType.GET_TRANSACTION); + request.setData(transactionHash.getBytes()); + web3Connection.asyncSend( + request, + response -> { + assertEquals(response.getErrorCode(), Web3StatusCode.Success); + TransactionPair transactionPair = null; + try { + transactionPair = objectMapper.readValue(response.getData(), TransactionPair.class); + } catch (IOException e) { + e.printStackTrace(); + } + assertTrue(Objects.nonNull(transactionPair)); + Transaction transaction = transactionPair.getTransaction(); + TransactionReceipt transactionReceipt = transactionPair.getTransactionReceipt(); + assertTrue(Objects.nonNull(transaction)); + assertTrue(Objects.nonNull(transactionReceipt)); + assertEquals( + transaction.getHash(), + "0x4980adef7b9a6d2cd709cdbd1f308ddff18c6486b3a06fd85387450a87bce8c4"); + assertEquals( + transactionReceipt.getTransactionHash(), + "0x4980adef7b9a6d2cd709cdbd1f308ddff18c6486b3a06fd85387450a87bce8c4"); + }); + } + + @Test + public void handleCallTest() throws JsonProcessingException { + String method = "get"; + String[] params = new String[] {}; + TransactionRequest transactionRequest = new TransactionRequest(method, params); + + Function function = + new Function( + method, Collections.emptyList(), Arrays.asList(new TypeReference() {})); + String from = "0xaff0ca253b97e54440965855cec0a8a2e2399896"; + String to = "0x7cf92bd66acacf18f46a4e2dc0280cd67bfae923"; + String data = FunctionEncoder.encode(function); + String abi = + "[{\"constant\":false,\"inputs\":[{\"name\":\"n\",\"type\":\"string\"}],\"name\":\"set\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"get\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}]"; + TransactionParams transactionParams = + new TransactionParams( + transactionRequest, TransactionParams.SUB_TYPE.CALL, from, to, data, abi); + + Request request = new Request(); + request.setType(Web3RequestType.CALL); + request.setData(ObjectMapperFactory.getObjectMapper().writeValueAsBytes(transactionParams)); + + web3Connection.asyncSend( + request, + response -> { + assertEquals(response.getErrorCode(), Web3StatusCode.Success); + + EthCall ethCall = null; + try { + ethCall = objectMapper.readValue(response.getData(), EthCall.class); + } catch (IOException e) { + e.printStackTrace(); + } + assertTrue(Objects.nonNull(ethCall)); + assertFalse(ethCall.hasError()); + assertEquals(data, ethCall.getResult()); + }); + } + + @Test + public void handleSendTransactionTest() throws IOException { + String method = "set"; + String[] params = new String[] {"hello world!!!"}; + TransactionRequest transactionRequest = new TransactionRequest(method, params); + Function function = + new Function( + method, Arrays.asList(new Utf8String("hello world!!!")), Collections.emptyList()); + String data = FunctionEncoder.encode(function); + + ClientWrapper clientWrapper = web3Connection.getClientWrapper(); + String privateKey = "4b9f63ecf84210c5366c66d68fa1f5da1fa4f634fad6dfc86178e4d79ff9e59"; + Credentials credentials = Credentials.create(privateKey); + RawTransaction rawTransaction = + RawTransaction.createTransaction( + clientWrapper.getNonce(credentials.getAddress()), + clientWrapper.ethGasPrice(), + clientWrapper.ethGasLimit(), + "0x7cf92bd66acacf18f46a4e2dc0280cd67bfae923", + data); + + byte[] signedMessage = + TransactionEncoder.signMessage( + rawTransaction, clientWrapper.ethChainId().longValue(), credentials); + String abi = + "[{\"constant\":false,\"inputs\":[{\"name\":\"n\",\"type\":\"string\"}],\"name\":\"set\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"get\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}]"; + + TransactionParams transactionParams = + new TransactionParams( + transactionRequest, + TransactionParams.SUB_TYPE.SEND_TX, + Numeric.toHexString(signedMessage), + abi); + + Request request = new Request(); + request.setType(Web3RequestType.SEND_TRANSACTION); + request.setData(ObjectMapperFactory.getObjectMapper().writeValueAsBytes(transactionParams)); + + web3Connection.asyncSend( + request, + response -> { + assertEquals(response.getErrorCode(), Web3StatusCode.Success); + + TransactionReceipt transactionReceipt = null; + try { + transactionReceipt = + objectMapper.readValue(response.getData(), TransactionReceipt.class); + } catch (IOException e) { + e.printStackTrace(); + } + assertTrue(Objects.nonNull(transactionReceipt)); + assertEquals(transactionReceipt.getBlockNumber().longValue(), 108214); + assertEquals( + transactionReceipt.getTransactionHash(), + "0x4980adef7b9a6d2cd709cdbd1f308ddff18c6486b3a06fd85387450a87bce8c4"); + assertEquals(transactionReceipt.getFrom(), credentials.getAddress()); + assertEquals(transactionReceipt.getTo(), "0x7cf92bd66acacf18f46a4e2dc0280cd67bfae923"); + }); + } +} diff --git a/src/test/java/com/webank/wecross/stub/web3/Web3StubFactoryTest.java b/src/test/java/com/webank/wecross/stub/web3/Web3StubFactoryTest.java new file mode 100644 index 0000000..ae6a5b1 --- /dev/null +++ b/src/test/java/com/webank/wecross/stub/web3/Web3StubFactoryTest.java @@ -0,0 +1,58 @@ +package com.webank.wecross.stub.web3; + +import static junit.framework.TestCase.assertEquals; +import static junit.framework.TestCase.assertFalse; +import static junit.framework.TestCase.assertTrue; + +import com.webank.wecross.stub.Account; +import com.webank.wecross.stub.Connection; +import com.webank.wecross.stub.Driver; +import com.webank.wecross.stub.web3.account.Web3Account; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import org.junit.Test; + +public class Web3StubFactoryTest { + + private final Web3StubFactory web3StubFactory = new Web3StubFactory(); + + @Test + public void newConnectionTest() { + Connection connection = web3StubFactory.newConnection("./"); + assertTrue(Objects.isNull(connection)); + } + + @Test + public void newDriverTest() { + Driver driver = web3StubFactory.newDriver(); + assertTrue(Objects.nonNull(driver)); + assertTrue(driver instanceof Web3Driver); + } + + @Test + public void newAccountTest() { + Map properties = new HashMap<>(); + properties.put("username", "wallet"); + properties.put("keyID", 1); + properties.put("type", "WEB3"); + properties.put("isDefault", false); + properties.put("secKey", "cd9d9b47e26ec14e4b86048d24db6a710770967d6f37bead3957ce2ebd8ba028"); + properties.put( + "pubKey", + "ab1c9d486b269adbb604766daf7d209440663299dd78b229ffcf728568b6b8a93c8a096ca4328d93040a0c8b4bd448e0e2da2566bf252845426f806a053d2cc6"); + properties.put("ext0", "0x698d83382f9ffb72271cd0826479e8ab02077842"); + + Account account = web3StubFactory.newAccount(properties); + assertTrue(account instanceof Web3Account); + + assertEquals(account.getName(), "wallet"); + assertEquals(account.getType(), "WEB3"); + assertEquals(account.getKeyID(), 1); + assertEquals(account.getIdentity(), "0x698d83382f9ffb72271cd0826479e8ab02077842"); + assertEquals( + ((Web3Account) account).getPublicKey(), + "ab1c9d486b269adbb604766daf7d209440663299dd78b229ffcf728568b6b8a93c8a096ca4328d93040a0c8b4bd448e0e2da2566bf252845426f806a053d2cc6"); + assertFalse(account.isDefault()); + } +} diff --git a/src/test/java/com/webank/wecross/stub/web3/account/Web3AccountTest.java b/src/test/java/com/webank/wecross/stub/web3/account/Web3AccountTest.java new file mode 100644 index 0000000..1afb801 --- /dev/null +++ b/src/test/java/com/webank/wecross/stub/web3/account/Web3AccountTest.java @@ -0,0 +1,24 @@ +package com.webank.wecross.stub.web3.account; + +import static junit.framework.TestCase.assertEquals; +import static junit.framework.TestCase.assertFalse; + +import java.security.InvalidAlgorithmParameterException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import org.junit.Test; +import org.web3j.crypto.Credentials; +import org.web3j.crypto.Keys; + +public class Web3AccountTest { + @Test + public void accountTest() + throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException { + Credentials credentials = Credentials.create(Keys.createEcKeyPair()); + Web3Account account = new Web3Account("test", "type", credentials); + assertEquals(account.getName(), "test"); + assertEquals(account.getType(), "type"); + assertFalse(account.getIdentity().isEmpty()); + assertFalse(account.getPublicKey().isEmpty()); + } +} diff --git a/src/test/java/com/webank/wecross/stub/web3/client/ClientWrapperImplMock.java b/src/test/java/com/webank/wecross/stub/web3/client/ClientWrapperImplMock.java new file mode 100644 index 0000000..0777f85 --- /dev/null +++ b/src/test/java/com/webank/wecross/stub/web3/client/ClientWrapperImplMock.java @@ -0,0 +1,98 @@ +package com.webank.wecross.stub.web3.client; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import java.io.IOException; +import java.math.BigInteger; +import java.security.SecureRandom; +import org.reactivestreams.Subscriber; +import org.web3j.protocol.ObjectMapperFactory; +import org.web3j.protocol.core.methods.request.EthFilter; +import org.web3j.protocol.core.methods.response.EthBlock; +import org.web3j.protocol.core.methods.response.EthCall; +import org.web3j.protocol.core.methods.response.EthSendTransaction; +import org.web3j.protocol.core.methods.response.Log; +import org.web3j.protocol.core.methods.response.Transaction; +import org.web3j.protocol.core.methods.response.TransactionReceipt; + +public class ClientWrapperImplMock extends ClientWrapperImpl { + private final ObjectMapper objectMapper = ObjectMapperFactory.getObjectMapper(); + + public ClientWrapperImplMock() { + super(null); + this.objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS); + } + + @Override + public EthBlock.Block ethGetBlockByNumber(BigInteger blockNumber) throws IOException { + String blockJson = + "{\"number\":108214,\"hash\":\"0x8abe7ca191df7a3b0cc3f081d6d5a1bd2d542bb6a6b7a5c6a9e75244d90c5aad\",\"parentHash\":\"0x21a26483f5968cdaecfc8a85bd92fda6692ceee52b6716dd2c8fa65225820496\",\"nonce\":0,\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"transactionsRoot\":\"0xe7acf5d55d7d2e63d7c0989660a72cf099539be3abe06a446b1db73b3ff5adf4\",\"stateRoot\":\"0x2473e460d2818392c43f5775203c160d23fa13774b82798687cf99e3db7ec054\",\"receiptsRoot\":\"0x3998b0b006ea68156060551908975d78935a9add49a23f65ce497af6a5be311e\",\"author\":null,\"miner\":\"0x8943545177806ed17b9f23f0a21ee5948ecaa776\",\"mixHash\":\"0x928fe08f6690213632620d84bae3826710c959bf9f079001a75c6ff537932c19\",\"difficulty\":0,\"totalDifficulty\":1,\"extraData\":\"0xd883010e07846765746888676f312e32322e35856c696e7578\",\"size\":816,\"gasLimit\":30000000,\"gasUsed\":24780,\"timestamp\":1723105141,\"transactions\":[{\"hash\":\"0x4980adef7b9a6d2cd709cdbd1f308ddff18c6486b3a06fd85387450a87bce8c4\",\"nonce\":77,\"blockHash\":\"0x8abe7ca191df7a3b0cc3f081d6d5a1bd2d542bb6a6b7a5c6a9e75244d90c5aad\",\"blockNumber\":108214,\"chainId\":1337,\"transactionIndex\":0,\"from\":\"0xaff0ca253b97e54440965855cec0a8a2e2399896\",\"to\":\"0x7cf92bd66acacf18f46a4e2dc0280cd67bfae923\",\"value\":0,\"gasPrice\":22000000000,\"gas\":4300000,\"input\":\"0x4ed3885e0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000e78697869786978692121217e7e7e000000000000000000000000000000000000\",\"creates\":null,\"publicKey\":null,\"raw\":null,\"r\":\"0x4e608162ddfc7e43284df9d8d6e40b151b116fcb0f7c14690c0a92ead1214c30\",\"s\":\"0x49789a1f93f74ef1060048a5871604c4419650ced2ab37786094f2cdd5677224\",\"v\":2710,\"type\":\"0x0\",\"maxFeePerGas\":null,\"maxPriorityFeePerGas\":null,\"accessList\":null,\"transactionIndexRaw\":\"0x0\",\"blockNumberRaw\":\"0x1a6b6\",\"maxPriorityFeePerGasRaw\":null,\"gasPriceRaw\":\"0x51f4d5c00\",\"nonceRaw\":\"0x4d\",\"gasRaw\":\"0x419ce0\",\"valueRaw\":\"0x0\",\"chainIdRaw\":\"0x539\",\"maxFeePerGasRaw\":null}],\"uncles\":[],\"sealFields\":null,\"baseFeePerGas\":7,\"gasUsedRaw\":\"0x60cc\",\"nonceRaw\":\"0x0000000000000000\",\"difficultyRaw\":\"0x0\",\"sizeRaw\":\"0x330\",\"numberRaw\":\"0x1a6b6\",\"gasLimitRaw\":\"0x1c9c380\",\"timestampRaw\":\"0x66b47f75\",\"totalDifficultyRaw\":\"0x1\",\"baseFeePerGasRaw\":\"0x7\"}"; + return objectMapper.readValue(blockJson, EthBlock.Block.class); + } + + @Override + public BigInteger ethBlockNumber() throws IOException { + return BigInteger.valueOf(108214); + } + + @Override + public EthSendTransaction ethSendRawTransaction(String signedTransactionData) throws IOException { + String transactionHash = "0x4980adef7b9a6d2cd709cdbd1f308ddff18c6486b3a06fd85387450a87bce8c4"; + EthSendTransaction ethSendTransaction = new EthSendTransaction(); + ethSendTransaction.setResult(transactionHash); + return ethSendTransaction; + } + + @Override + public TransactionReceipt ethGetTransactionReceipt(String transactionHash) throws Exception { + String transactionReceiptJson = + "{\"transactionHash\":\"0x4980adef7b9a6d2cd709cdbd1f308ddff18c6486b3a06fd85387450a87bce8c4\",\"transactionIndex\":0,\"blockHash\":\"0x8abe7ca191df7a3b0cc3f081d6d5a1bd2d542bb6a6b7a5c6a9e75244d90c5aad\",\"blockNumber\":108214,\"cumulativeGasUsed\":24780,\"gasUsed\":24780,\"contractAddress\":null,\"root\":null,\"status\":\"0x1\",\"from\":\"0xaff0ca253b97e54440965855cec0a8a2e2399896\",\"to\":\"0x7cf92bd66acacf18f46a4e2dc0280cd67bfae923\",\"logs\":[],\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"revertReason\":null,\"type\":\"0x0\",\"effectiveGasPrice\":\"0x51f4d5c00\",\"statusOK\":true,\"blockNumberRaw\":\"0x1a6b6\",\"gasUsedRaw\":\"0x60cc\",\"cumulativeGasUsedRaw\":\"0x60cc\",\"transactionIndexRaw\":\"0x0\"}"; + return objectMapper.readValue(transactionReceiptJson, TransactionReceipt.class); + } + + @Override + public Transaction ethGetTransactionByHash(String transactionHash) throws IOException { + String transactionJson = + "{\"hash\":\"0x4980adef7b9a6d2cd709cdbd1f308ddff18c6486b3a06fd85387450a87bce8c4\",\"nonce\":77,\"blockHash\":\"0x8abe7ca191df7a3b0cc3f081d6d5a1bd2d542bb6a6b7a5c6a9e75244d90c5aad\",\"blockNumber\":108214,\"chainId\":1337,\"transactionIndex\":0,\"from\":\"0xaff0ca253b97e54440965855cec0a8a2e2399896\",\"to\":\"0x7cf92bd66acacf18f46a4e2dc0280cd67bfae923\",\"value\":0,\"gasPrice\":22000000000,\"gas\":4300000,\"input\":\"0x4ed3885e0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000e78697869786978692121217e7e7e000000000000000000000000000000000000\",\"creates\":null,\"publicKey\":null,\"raw\":null,\"r\":\"0x4e608162ddfc7e43284df9d8d6e40b151b116fcb0f7c14690c0a92ead1214c30\",\"s\":\"0x49789a1f93f74ef1060048a5871604c4419650ced2ab37786094f2cdd5677224\",\"v\":2710,\"type\":\"0x0\",\"maxFeePerGas\":null,\"maxPriorityFeePerGas\":null,\"accessList\":null,\"transactionIndexRaw\":\"0x0\",\"blockNumberRaw\":\"0x1a6b6\",\"maxPriorityFeePerGasRaw\":null,\"maxFeePerGasRaw\":null,\"nonceRaw\":\"0x4d\",\"valueRaw\":\"0x0\",\"gasPriceRaw\":\"0x51f4d5c00\",\"gasRaw\":\"0x419ce0\",\"chainIdRaw\":\"0x539\"}"; + return objectMapper.readValue(transactionJson, Transaction.class); + } + + @Override + public EthCall ethCall(org.web3j.protocol.core.methods.request.Transaction transaction) + throws IOException { + EthCall ethCall = new EthCall(); + ethCall.setId(1); + ethCall.setJsonrpc("2.0"); + ethCall.setResult(transaction.getData()); + return ethCall; + } + + @Override + public BigInteger getNonce(String address) { + SecureRandom random = new SecureRandom(); + return BigInteger.probablePrime(64, random); + } + + @Override + public BigInteger ethChainId() { + return BigInteger.valueOf(1337); + } + + @Override + public BigInteger ethGasPrice() { + return BigInteger.valueOf(22_000_000_000L); + } + + @Override + public BigInteger ethGasLimit() { + return BigInteger.valueOf(4_300_000); + } + + @Override + public void subscribe(EthFilter ethFilter, Subscriber subscriber) {} + + @Override + public String extractRevertReason(TransactionReceipt transactionReceipt, String data) { + return "execution reverted: method reverted!"; + } +} diff --git a/src/test/java/com/webank/wecross/stub/web3/client/ClientWrapperNotSuccessStatus.java b/src/test/java/com/webank/wecross/stub/web3/client/ClientWrapperNotSuccessStatus.java new file mode 100644 index 0000000..ded5e3f --- /dev/null +++ b/src/test/java/com/webank/wecross/stub/web3/client/ClientWrapperNotSuccessStatus.java @@ -0,0 +1,20 @@ +package com.webank.wecross.stub.web3.client; + +import org.web3j.protocol.core.Response; +import org.web3j.protocol.core.methods.request.Transaction; +import org.web3j.protocol.core.methods.response.EthCall; + +public class ClientWrapperNotSuccessStatus extends ClientWrapperImplMock { + + @Override + public EthCall ethCall(Transaction transaction) { + Response.Error error = new Response.Error(); + error.setCode(3); + error.setMessage("execution reverted: method reverted!"); + EthCall ethCall = new EthCall(); + ethCall.setId(1); + ethCall.setJsonrpc("2.0"); + ethCall.setError(error); + return ethCall; + } +} diff --git a/src/test/java/com/webank/wecross/stub/web3/client/ClientWrapperWithExceptionMock.java b/src/test/java/com/webank/wecross/stub/web3/client/ClientWrapperWithExceptionMock.java new file mode 100644 index 0000000..c21c18e --- /dev/null +++ b/src/test/java/com/webank/wecross/stub/web3/client/ClientWrapperWithExceptionMock.java @@ -0,0 +1,45 @@ +package com.webank.wecross.stub.web3.client; + +import java.io.IOException; +import java.math.BigInteger; +import org.web3j.protocol.core.methods.response.EthBlock; +import org.web3j.protocol.core.methods.response.EthCall; +import org.web3j.protocol.core.methods.response.EthSendTransaction; +import org.web3j.protocol.core.methods.response.Transaction; +import org.web3j.protocol.core.methods.response.TransactionReceipt; + +public class ClientWrapperWithExceptionMock extends ClientWrapperImplMock { + + public ClientWrapperWithExceptionMock() {} + + @Override + public EthBlock.Block ethGetBlockByNumber(BigInteger blockNumber) throws IOException { + throw new IOException("IOException"); + } + + @Override + public BigInteger ethBlockNumber() throws IOException { + throw new IOException("IOException"); + } + + @Override + public EthSendTransaction ethSendRawTransaction(String signedTransactionData) throws IOException { + throw new IOException("IOException"); + } + + @Override + public TransactionReceipt ethGetTransactionReceipt(String transactionHash) throws Exception { + throw new IOException("IOException"); + } + + @Override + public Transaction ethGetTransactionByHash(String transactionHash) throws IOException { + throw new IOException("IOException"); + } + + @Override + public EthCall ethCall(org.web3j.protocol.core.methods.request.Transaction transaction) + throws IOException { + throw new IOException("IOException"); + } +} diff --git a/src/test/java/com/webank/wecross/stub/web3/client/ClientWrapperWithNullMock.java b/src/test/java/com/webank/wecross/stub/web3/client/ClientWrapperWithNullMock.java new file mode 100644 index 0000000..ac63184 --- /dev/null +++ b/src/test/java/com/webank/wecross/stub/web3/client/ClientWrapperWithNullMock.java @@ -0,0 +1,41 @@ +package com.webank.wecross.stub.web3.client; + +import java.math.BigInteger; +import org.web3j.protocol.core.methods.response.EthBlock; +import org.web3j.protocol.core.methods.response.EthCall; +import org.web3j.protocol.core.methods.response.EthSendTransaction; +import org.web3j.protocol.core.methods.response.Transaction; +import org.web3j.protocol.core.methods.response.TransactionReceipt; + +public class ClientWrapperWithNullMock extends ClientWrapperImplMock { + + @Override + public BigInteger ethBlockNumber() { + return null; + } + + @Override + public EthBlock.Block ethGetBlockByNumber(BigInteger blockNumber) { + return null; + } + + @Override + public EthSendTransaction ethSendRawTransaction(String signedTransactionData) { + return null; + } + + @Override + public TransactionReceipt ethGetTransactionReceipt(String transactionHash) { + return null; + } + + @Override + public Transaction ethGetTransactionByHash(String transactionHash) { + return null; + } + + @Override + public EthCall ethCall(org.web3j.protocol.core.methods.request.Transaction transaction) { + return null; + } +} diff --git a/src/test/java/com/webank/wecross/stub/web3/common/Web3ConstantTest.java b/src/test/java/com/webank/wecross/stub/web3/common/Web3ConstantTest.java new file mode 100644 index 0000000..4a060e7 --- /dev/null +++ b/src/test/java/com/webank/wecross/stub/web3/common/Web3ConstantTest.java @@ -0,0 +1,33 @@ +package com.webank.wecross.stub.web3.common; + +import static junit.framework.TestCase.assertEquals; + +import com.webank.wecross.stub.StubConstant; +import org.junit.Test; + +public class Web3ConstantTest { + + @Test + public void constantValueTest() { + assertEquals(Web3Constant.STUB_TOML_NAME, "stub.toml"); + assertEquals(Web3Constant.ACCOUNT_TOML_NAME, "account.toml"); + assertEquals(Web3Constant.WEB3_STUB_TYPE, "WEB3"); + assertEquals(Web3Constant.WEB3_CONTRACT_TYPE, "WEB3_CONTRACT"); + assertEquals(Web3Constant.WEB3_PROXY_NAME, StubConstant.PROXY_NAME); + assertEquals(Web3Constant.WEB3_HUB_NAME, StubConstant.HUB_NAME); + assertEquals(Web3Constant.WEB3_PROPERTY_ABI_SUFFIX, "ABI"); + assertEquals(Web3Constant.WEB3_PROPERTY_CHAIN_ID, "WEB3_PROPERTY_CHAIN_ID"); + assertEquals(Web3Constant.WEB3_PROPERTY_STUB_TYPE, "WEB3_PROPERTY_STUB_TYPE"); + assertEquals(Web3Constant.WEB3_PROPERTY_CHAIN_URL, "WEB3_PROPERTY_CHAIN_URL"); + assertEquals(Web3Constant.CUSTOM_COMMAND_REGISTER, "register"); + } + + @Test + public void requestTypeTest() { + assertEquals(Web3RequestType.CALL, 1000); + assertEquals(Web3RequestType.SEND_TRANSACTION, 1001); + assertEquals(Web3RequestType.GET_BLOCK_NUMBER, 1002); + assertEquals(Web3RequestType.GET_BLOCK_BY_NUMBER, 1003); + assertEquals(Web3RequestType.GET_TRANSACTION, 1004); + } +} diff --git a/src/test/java/com/webank/wecross/stub/web3/common/Web3StubConfigParserTest.java b/src/test/java/com/webank/wecross/stub/web3/common/Web3StubConfigParserTest.java new file mode 100644 index 0000000..1fdfb2c --- /dev/null +++ b/src/test/java/com/webank/wecross/stub/web3/common/Web3StubConfigParserTest.java @@ -0,0 +1,45 @@ +package com.webank.wecross.stub.web3.common; + +import static junit.framework.TestCase.assertEquals; +import static junit.framework.TestCase.assertTrue; + +import com.webank.wecross.stub.web3.config.Web3StubConfig; +import com.webank.wecross.stub.web3.config.Web3StubConfigParser; +import java.io.IOException; +import java.util.List; +import java.util.Objects; +import org.junit.Test; + +public class Web3StubConfigParserTest { + @Test + public void stubConfigParserTest() throws IOException { + Web3StubConfigParser web3StubConfigParser = new Web3StubConfigParser("./", "stub-sample.toml"); + Web3StubConfig web3StubConfig = web3StubConfigParser.loadConfig(); + Web3StubConfig.Common common = web3StubConfig.getCommon(); + Web3StubConfig.Service service = web3StubConfig.getService(); + List resources = web3StubConfig.getResources(); + + assertTrue(Objects.nonNull(common)); + assertTrue(Objects.nonNull(service)); + assertTrue(Objects.nonNull(resources) && !resources.isEmpty()); + + assertEquals(common.getName(), "web3"); + assertEquals(common.getType(), "WEB3"); + + assertEquals(service.getUrl(), "http://localhost:8545"); + + assertEquals(resources.size(), 2); + assertEquals(resources.get(0).getName(), "WeCrossProxy"); + assertEquals(resources.get(0).getType(), "WEB3_CONTRACT"); + assertEquals(resources.get(0).getAddress(), "0xdbF599778641083c9717Ec69e984D67d3309B811"); + assertEquals( + resources.get(0).getAbi(), + "[{\"constant\":false,\"inputs\":[{\"name\":\"n\",\"type\":\"string\"}],\"name\":\"set\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"get\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}]"); + assertEquals(resources.get(1).getName(), "WeCrossHub"); + assertEquals(resources.get(1).getType(), "WEB3_CONTRACT"); + assertEquals(resources.get(1).getAddress(), "0xdbF599778641083c9717Ec69e984D67d3309B811"); + assertEquals( + resources.get(1).getAbi(), + "[{\"constant\":false,\"inputs\":[{\"name\":\"n\",\"type\":\"string\"}],\"name\":\"set\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"get\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}]"); + } +} diff --git a/src/test/java/com/webank/wecross/stub/web3/common/Web3TomlTest.java b/src/test/java/com/webank/wecross/stub/web3/common/Web3TomlTest.java new file mode 100644 index 0000000..65ea7ae --- /dev/null +++ b/src/test/java/com/webank/wecross/stub/web3/common/Web3TomlTest.java @@ -0,0 +1,19 @@ +package com.webank.wecross.stub.web3.common; + +import static junit.framework.TestCase.assertEquals; +import static junit.framework.TestCase.assertTrue; + +import java.io.IOException; +import java.util.Objects; +import org.junit.Test; + +public class Web3TomlTest { + + @Test + public void loadTomlTest() throws IOException { + String filePath = "./stub-sample.toml"; + Web3Toml web3Toml = new Web3Toml(filePath); + assertEquals(web3Toml.getPath(), filePath); + assertTrue(Objects.nonNull(web3Toml.getToml())); + } +} diff --git a/src/test/resources/account/698d83382f9ffb72271cd0826479e8ab02077842.json b/src/test/resources/account/698d83382f9ffb72271cd0826479e8ab02077842.json new file mode 100644 index 0000000..f009d47 --- /dev/null +++ b/src/test/resources/account/698d83382f9ffb72271cd0826479e8ab02077842.json @@ -0,0 +1 @@ +{"address":"698d83382f9ffb72271cd0826479e8ab02077842","id":"60995194-2f01-4d69-a51c-64f67e090367","version":3,"crypto":{"cipher":"aes-128-ctr","ciphertext":"61c51037b3eb3a03323c5fb2a04419a13ac8df8750201eb3bcaf69261fc6a358","cipherparams":{"iv":"670cc63ccdbd45b422bdf1b869eea14d"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"4e991d6279f2d56867ab8934fefc560dbc1e6d5e3cf76e2e054a587e31b5abc5"},"mac":"fe2b5f4a358d435f58df795616c1b09d15839a31cddb6964e76b2dc9954711a7"}} \ No newline at end of file diff --git a/src/test/resources/account/account.toml b/src/test/resources/account/account.toml new file mode 100644 index 0000000..8986dd9 --- /dev/null +++ b/src/test/resources/account/account.toml @@ -0,0 +1,4 @@ +[account] + type = "WEB3" + accountFile = '698d83382f9ffb72271cd0826479e8ab02077842.json' + password = '123456' \ No newline at end of file diff --git a/src/test/resources/log4j.properties b/src/test/resources/log4j.properties new file mode 100644 index 0000000..11bfd6f --- /dev/null +++ b/src/test/resources/log4j.properties @@ -0,0 +1,49 @@ +### set log levels ### +log4j.rootLogger = INFO, info, error + +### output the TRACE level log information to the =./log/trace.log ### +log4j.appender.trace = org.apache.log4j.DailyRollingFileAppender +log4j.appender.trace.File = ./log/all.log +log4j.appender.trace.Append = true +log4j.appender.trace.Threshold = TRACE +log4j.appender.trace.filter.traceFilter = org.apache.log4j.varia.LevelRangeFilter +log4j.appender.trace.filter.traceFilter.levelMin = TRACE +log4j.appender.trace.filter.traceFilter.levelMax = TRACE +log4j.appender.trace.layout = org.apache.log4j.PatternLayout +log4j.appender.trace.layout.ConversionPattern = [%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C{1}.%M(%L) | %m%n + +### output the DEBUG level log information to the =./log/debug.log ### +log4j.appender.debug = org.apache.log4j.DailyRollingFileAppender +log4j.appender.debug.File = ./log/all.log +log4j.appender.debug.Append = true +log4j.appender.debug.Threshold = DEBUG +log4j.appender.debug.filter.debugFilter = org.apache.log4j.varia.LevelRangeFilter +log4j.appender.debug.filter.debugFilter.levelMin = DEBUG +log4j.appender.debug.filter.debugFilter.levelMax = DEBUG +log4j.appender.debug.layout = org.apache.log4j.PatternLayout +log4j.appender.debug.layout.ConversionPattern = [%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C{1}.%M(%L) | %m%n + +### output the INFO level log information to the =./log/info.log ### +log4j.appender.info = org.apache.log4j.DailyRollingFileAppender +log4j.appender.info.File = ./log/all.log +log4j.appender.info.Append = true +log4j.appender.info.Threshold = INFO +log4j.appender.info.filter.infoFilter = org.apache.log4j.varia.LevelRangeFilter +log4j.appender.info.filter.infoFilter.levelMin = INFO +log4j.appender.info.filter.infoFilter.levelMax = INFO +log4j.appender.info.layout = org.apache.log4j.PatternLayout +log4j.appender.info.layout.ConversionPattern = [%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C{1}.%M(%L) | %m%n + +### output the ERROR level log information to the=./log/error.log ### +log4j.appender.error = org.apache.log4j.DailyRollingFileAppender +log4j.appender.error.File = ./log/all.log +log4j.appender.error.Append = true +log4j.appender.error.Threshold = ERROR +log4j.appender.error.layout = org.apache.log4j.PatternLayout +log4j.appender.error.layout.ConversionPattern = [%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C{1}.%M(%L) | %m%n + +###output the log information to the console ### +log4j.appender.stdout = org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target = System.out +log4j.appender.stdout.layout = org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern = [%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C{1}.%M(%L) | %m%n diff --git a/src/test/resources/stub-sample.toml b/src/test/resources/stub-sample.toml new file mode 100644 index 0000000..2ccebf0 --- /dev/null +++ b/src/test/resources/stub-sample.toml @@ -0,0 +1,19 @@ +[common] + name = 'web3' # stub must be same with directory name + type = 'WEB3' # WEB3 + +[service] + url = 'http://localhost:8545' + +[[resources]] + name = 'WeCrossProxy' + type = 'WEB3_CONTRACT' + address = '0xdbF599778641083c9717Ec69e984D67d3309B811' + abi = '[{"constant":false,"inputs":[{"name":"n","type":"string"}],"name":"set","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"}]' + +[[resources]] + name = 'WeCrossHub' + type = 'WEB3_CONTRACT' + address = '0xdbF599778641083c9717Ec69e984D67d3309B811' + abi = '[{"constant":false,"inputs":[{"name":"n","type":"string"}],"name":"set","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"}]' +