Skip to content

Commit

Permalink
<feat>(account): init account code
Browse files Browse the repository at this point in the history
  • Loading branch information
yangfang2 committed Aug 5, 2024
1 parent 03c6fe3 commit 1c6f5aa
Show file tree
Hide file tree
Showing 13 changed files with 364 additions and 209 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.webank.wecross.stub.web3;

import com.webank.wecross.stub.Account;
import com.webank.wecross.stub.Connection;
import com.webank.wecross.stub.Driver;
import com.webank.wecross.stub.StubFactory;
import com.webank.wecross.stub.WeCrossContext;
import com.webank.wecross.stub.web3.account.Web3AccountFactory;
import com.webank.wecross.stub.web3.common.Web3Constant;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Web3BaseStubFactory implements StubFactory {
private static final Logger logger = LoggerFactory.getLogger(Web3BaseStubFactory.class);

@Override
public void init(WeCrossContext weCrossContext) {}

@Override
public Driver newDriver() {
return null;
}

@Override
public Connection newConnection(String path) {
try {
logger.info("New connection: {}", path);
Web3Connection connection = Web3ConnectionFactory.build(path, Web3Constant.STUB_TOML_NAME);

// check proxy contract
if (!connection.hasProxyDeployed()) {
String errorMsg = "WeCrossProxy error: WeCrossProxy contract has not been deployed!";
System.out.println(errorMsg);
throw new Exception(errorMsg);
}

// check hub contract
if (!connection.hasHubDeployed()) {
String errorMsg = "WeCrossHub error: WeCrossHub contract has not been deployed!";
System.out.println(errorMsg);
throw new Exception(errorMsg);
}
return connection;
} catch (Exception e) {
logger.error("New connection fail, e: ", e);
return null;
}
}

@Override
public Account newAccount(Map<String, Object> properties) {
return Web3AccountFactory.build(properties);
}

@Override
public void generateAccount(String path, String[] args) {}

@Override
public void generateConnection(String path, String[] args) {}
}
137 changes: 3 additions & 134 deletions src/main/java/com/webank/wecross/stub/web3/Web3Connection.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,74 +12,39 @@
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.common.Web3StubException;
import com.webank.wecross.stub.web3.config.Web3StubConfig;
import com.webank.wecross.stub.web3.protocol.request.TransactionParams;
import com.webank.wecross.stub.web3.protocol.response.TransactionPair;
import com.webank.wecross.stub.web3.utils.FunctionUtility;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.web3j.abi.FunctionEncoder;
import org.web3j.abi.datatypes.Function;
import org.web3j.crypto.Credentials;
import org.web3j.crypto.RawTransaction;
import org.web3j.crypto.TransactionDecoder;
import org.web3j.crypto.TransactionEncoder;
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;
import org.web3j.utils.Numeric;

public class Web3Connection implements Connection {
private static final Logger logger = LoggerFactory.getLogger(Web3Connection.class);
public static final String RECEIPT_SUCCESS = "0x1";

private final ObjectMapper objectMapper = ObjectMapperFactory.getObjectMapper();
private List<ResourceInfo> resourceInfoList = new ArrayList<>();
private List<ResourceInfo> resourcesCache = new ArrayList<>();
private ConnectionEventHandler eventHandler;
private final Map<String, String> properties = new HashMap<>();
private final ClientWrapper clientWrapper;

private final BigInteger chainId;
private final BigInteger gasPrice;
private final BigInteger gasLimit;

public Web3Connection(
BigInteger chainId,
Web3StubConfig web3StubConfig,
ClientWrapper clientWrapper,
ScheduledExecutorService scheduledExecutorService) {
public Web3Connection(ClientWrapper clientWrapper) {
this.objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
this.clientWrapper = clientWrapper;
this.chainId = chainId;
this.gasPrice = web3StubConfig.getService().getGasPrice();
this.gasLimit = web3StubConfig.getService().getGasLimit();

// refresh resource
scheduledExecutorService.scheduleAtFixedRate(
() -> {
if (Objects.nonNull(eventHandler)) {
noteOnResourcesChange();
}
},
10000,
30000,
TimeUnit.MILLISECONDS);
}

@Override
Expand Down Expand Up @@ -227,8 +192,8 @@ private void handleAsyncCallRequest(Request request, Callback callback) {

// build Transaction
org.web3j.protocol.core.methods.request.Transaction transaction =
org.web3j.protocol.core.methods.request.Transaction.createFunctionCallTransaction(
from, nonce, gasPrice, gasLimit, to, data);
org.web3j.protocol.core.methods.request.Transaction.createEthCallTransaction(
from, to, data);
EthCall ethCall = clientWrapper.ethCall(transaction);

// ethCall has error
Expand Down Expand Up @@ -314,102 +279,6 @@ private void handleAsyncTransactionRequest(Request request, Callback callback) {
}
}

private void noteOnResourcesChange() {
synchronized (this) {
List<ResourceInfo> resources = getResources();
if (!resources.equals(resourcesCache) && !resources.isEmpty()) {
eventHandler.onResourcesChange(resources);
resourcesCache = resources;
if (logger.isDebugEnabled()) {
logger.debug("resources notify, resources: {}", resources);
}
}
}
}

public List<ResourceInfo> getResources() {
List<ResourceInfo> resourceInfos =
new ArrayList<ResourceInfo>() {
{
addAll(resourceInfoList);
}
};
String[] resources = listResources();
if (Objects.nonNull(resources)) {
for (String resource : resources) {
ResourceInfo resourceInfo = new ResourceInfo();
resourceInfo.setStubType(getProperty(Web3Constant.WEB3_PROPERTY_STUB_TYPE));
resourceInfo.setName(resource);
Map<Object, Object> resourceProperties = resourceInfo.getProperties();
resourceProperties.put(
Web3Constant.WEB3_PROPERTY_CHAIN_ID, getProperty(Web3Constant.WEB3_PROPERTY_CHAIN_ID));
resourceInfos.add(resourceInfo);
}
}
return resourceInfos;
}

public String[] listResources() {
try {
Function function =
FunctionUtility.newDefaultFunction(FunctionUtility.ProxyGetResourcesMethodName, null);
String data = FunctionEncoder.encode(function);
String from = Web3Constant.DEFAULT_ADDRESS;
String to = properties.get(Web3Constant.WEB3_PROXY_NAME);
BigInteger nonce = clientWrapper.getNonce(from);
org.web3j.protocol.core.methods.request.Transaction callTransaction =
org.web3j.protocol.core.methods.request.Transaction.createFunctionCallTransaction(
from, nonce, gasPrice, gasLimit, to, data);
EthCall ethCall = clientWrapper.ethCall(callTransaction);

if (ethCall.hasError()) {
logger.error("listResources failed, error {}", ethCall.getError().getMessage());
throw new Web3StubException(
Web3StatusCode.ListResourcesFailed, ethCall.getError().getMessage());
}
String[] resources = FunctionUtility.decodeDefaultOutput(ethCall.getResult());
Set<String> set = new LinkedHashSet<>();
if (Objects.nonNull(resources) && resources.length != 0) {
for (int i = resources.length - 1; i >= 0; i--) {
set.add(resources[i]);
}
} else {
logger.debug("No path found and add system resources");
}
return set.toArray(new String[0]);
} catch (Exception e) {
logger.error("listPaths failed,", e);
return null;
}
}

public void registerCNS(String path, String address) {
try {
// todo credentials where get
Credentials credentials = null;

Function function = FunctionUtility.newRegisterCNSProxyFunction(path, address);
String data = FunctionEncoder.encode(function);

String to = properties.get(Web3Constant.WEB3_PROXY_NAME);
BigInteger nonce = clientWrapper.getNonce(credentials.getAddress());
RawTransaction rawTransaction =
RawTransaction.createTransaction(nonce, gasPrice, gasLimit, to, data);
byte[] signedMessage =
TransactionEncoder.signMessage(rawTransaction, chainId.longValue(), credentials);
String signedTransactionData = Numeric.toHexString(signedMessage);
EthSendTransaction ethSendTransaction =
clientWrapper.ethSendRawTransaction(signedTransactionData);
if (ethSendTransaction.hasError()) {
logger.error("registerCNS failed, error {}", ethSendTransaction.getError().getMessage());
throw new Web3StubException(
Web3StatusCode.RegisterContractFailed, ethSendTransaction.getError().getMessage());
}
} catch (Exception e) {
logger.error("registerCNS fail,path:{},address:{}", path, address, e);
}
}

public boolean hasProxyDeployed() {
return getProperties().containsKey(Web3Constant.WEB3_PROXY_NAME);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,62 +8,36 @@
import java.io.IOException;
import java.math.BigInteger;
import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.concurrent.CustomizableThreadFactory;

public class Web3ConnectionFactory {
private static final Logger logger = LoggerFactory.getLogger(Web3ConnectionFactory.class);

public static Web3Connection build(String stubConfigPath, String configName) throws Exception {
ScheduledExecutorService executorService =
new ScheduledThreadPoolExecutor(4, new CustomizableThreadFactory("tmpChainMakerConn-"));
return build(stubConfigPath, configName, executorService);
}

public static Web3Connection build(
String stubConfigPath, String configName, ScheduledExecutorService executorService)
throws Exception {
Web3StubConfigParser web3StubConfigParser =
new Web3StubConfigParser(stubConfigPath, configName);
Web3StubConfig web3StubConfig = web3StubConfigParser.loadConfig();
return build(web3StubConfig, executorService);
return build(web3StubConfig);
}

public static Web3Connection build(Web3StubConfig web3StubConfig) throws IOException {
ScheduledExecutorService executorService =
new ScheduledThreadPoolExecutor(4, new CustomizableThreadFactory("tmpChainMakerConn-"));
return build(web3StubConfig, executorService);
}

public static Web3Connection build(
Web3StubConfig web3StubConfig, ScheduledExecutorService executorService) throws IOException {
ClientWrapper clientWrapper = ClientWrapperFactory.createClientWrapperInstance(web3StubConfig);
return build(web3StubConfig, clientWrapper, executorService);
return build(web3StubConfig, clientWrapper);
}

public static Web3Connection build(
Web3StubConfig web3StubConfig,
ClientWrapper clientWrapper,
ScheduledExecutorService executorService)
public static Web3Connection build(Web3StubConfig web3StubConfig, ClientWrapper clientWrapper)
throws IOException {
logger.info("web3StubConfig: {}", web3StubConfig);
BigInteger chainId = clientWrapper.ethChainId();

Web3Connection connection =
new Web3Connection(chainId, web3StubConfig, clientWrapper, executorService);
Web3Connection connection = new Web3Connection(clientWrapper);
connection.setResourceInfoList(web3StubConfig.convertToResourceInfos());
connection.addProperty(Web3Constant.WEB3_PROPERTY_CHAIN_ID, chainId.toString());
connection.addProperty(
Web3Constant.WEB3_PROPERTY_STUB_TYPE, web3StubConfig.getCommon().getType());
connection.addProperty(
Web3Constant.WEB3_PROPERTY_CHAIN_URL, web3StubConfig.getService().getUrl());
connection.addProperty(
Web3Constant.WEB3_PROPERTY_GAS_LIMIT, web3StubConfig.getService().getGasLimit().toString());
connection.addProperty(
Web3Constant.WEB3_PROPERTY_GAS_PRICE, web3StubConfig.getService().getGasPrice().toString());
// from config build resources
List<Web3StubConfig.Resource> resources = web3StubConfig.getResources();
if (!resources.isEmpty()) {
Expand All @@ -75,12 +49,6 @@ public static Web3Connection build(
// name+ABI->abi
connection.addAbi(name, resource.getAbi());
}

// after connection addProperty , need use proxy address
for (Web3StubConfig.Resource resource : resources) {
// registerCNS and addResource
connection.registerCNS("a.b." + resource.getName(), resource.getAddress());
}
}
return connection;
}
Expand Down
13 changes: 11 additions & 2 deletions src/main/java/com/webank/wecross/stub/web3/Web3StubFactory.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
package com.webank.wecross.stub.web3;

import static com.webank.wecross.stub.web3.common.Web3Constant.WEB3_STUB_TYPE;

import com.webank.wecross.stub.Stub;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Web3StubFactory {
private final Logger logger = LoggerFactory.getLogger(Web3StubFactory.class);
@Stub(WEB3_STUB_TYPE)
public class Web3StubFactory extends Web3BaseStubFactory {
private static final Logger logger = LoggerFactory.getLogger(Web3StubFactory.class);

public static void main(String[] args) {
System.out.printf(
"This is %s Stub Plugin. Please copy this file to router/plugin/%n", WEB3_STUB_TYPE);
}
}
Loading

0 comments on commit 1c6f5aa

Please sign in to comment.