From d53f0b5251ec1b5b4275cc12d72b9182c99ba7d9 Mon Sep 17 00:00:00 2001 From: yangfang2 Date: Mon, 12 Aug 2024 15:26:16 +0800 Subject: [PATCH] (block): block support serialization --- .../stub/web3/common/ObjectMapperFactory.java | 53 +++- .../protocol/response/TransactionCustom.java | 274 ++++++++++++++++++ 2 files changed, 326 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/webank/wecross/stub/web3/protocol/response/TransactionCustom.java diff --git a/src/main/java/com/webank/wecross/stub/web3/common/ObjectMapperFactory.java b/src/main/java/com/webank/wecross/stub/web3/common/ObjectMapperFactory.java index 56de2cc..8730f1c 100644 --- a/src/main/java/com/webank/wecross/stub/web3/common/ObjectMapperFactory.java +++ b/src/main/java/com/webank/wecross/stub/web3/common/ObjectMapperFactory.java @@ -1,9 +1,17 @@ package com.webank.wecross.stub.web3.common; +import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectReader; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.webank.wecross.stub.web3.protocol.response.TransactionCustom; +import java.io.IOException; +import org.web3j.protocol.core.methods.response.EthBlock; +import org.web3j.protocol.core.methods.response.Transaction; public class ObjectMapperFactory { private static final ObjectMapper DEFAULT_OBJECT_MAPPER = getObjectMapper(); @@ -24,7 +32,50 @@ private static ObjectMapper configureObjectMapper(ObjectMapper objectMapper) { objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true); objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - + // custom serialization + SimpleModule simpleModule = new SimpleModule(); + simpleModule.addSerializer(EthBlock.TransactionHash.class, new TransactionHashSerialize()); + simpleModule.addSerializer(Transaction.class, new TransactionSerialize()); return objectMapper; } + + public static class TransactionHashSerialize extends JsonSerializer { + @Override + public void serialize( + EthBlock.TransactionHash value, JsonGenerator gen, SerializerProvider serializers) + throws IOException { + gen.writeString(value.get()); + } + } + + public static class TransactionSerialize extends JsonSerializer { + @Override + public void serialize(Transaction value, JsonGenerator gen, SerializerProvider serializers) + throws IOException { + TransactionCustom transaction = new TransactionCustom(); + transaction.setHash(value.getHash()); + transaction.setNonce(value.getNonceRaw()); + transaction.setBlockHash(value.getBlockHash()); + transaction.setBlockNumber(value.getBlockNumberRaw()); + transaction.setChainId(value.getChainIdRaw()); + transaction.setTransactionIndex(value.getTransactionIndexRaw()); + transaction.setFrom(value.getFrom()); + transaction.setTo(value.getTo()); + transaction.setValue(value.getValueRaw()); + transaction.setGasPrice(value.getGasPriceRaw()); + transaction.setGas(value.getGasRaw()); + transaction.setInput(value.getInput()); + transaction.setCreates(value.getCreates()); + transaction.setPublicKey(value.getPublicKey()); + transaction.setRaw(value.getRaw()); + transaction.setR(value.getR()); + transaction.setS(value.getS()); + transaction.setV(value.getV()); + transaction.setType(value.getType()); + transaction.setMaxFeePerGas(value.getMaxFeePerGasRaw()); + transaction.setMaxPriorityFeePerGas(value.getMaxPriorityFeePerGasRaw()); + transaction.setAccessList(value.getAccessList()); + gen.writeObject(transaction); + } + } } diff --git a/src/main/java/com/webank/wecross/stub/web3/protocol/response/TransactionCustom.java b/src/main/java/com/webank/wecross/stub/web3/protocol/response/TransactionCustom.java new file mode 100644 index 0000000..7633eef --- /dev/null +++ b/src/main/java/com/webank/wecross/stub/web3/protocol/response/TransactionCustom.java @@ -0,0 +1,274 @@ +package com.webank.wecross.stub.web3.protocol.response; + +import java.math.BigInteger; +import java.util.List; +import org.web3j.crypto.TransactionUtils; +import org.web3j.protocol.core.methods.response.AccessListObject; +import org.web3j.utils.Numeric; + +/** Transaction serialize object, before Numeric.decodeQuantity() check null */ +public class TransactionCustom { + private String hash; + private String nonce; + private String blockHash; + private String blockNumber; + private String chainId; + private String transactionIndex; + private String from; + private String to; + private String value; + private String gasPrice; + private String gas; + private String input; + private String creates; + private String publicKey; + private String raw; + private String r; + private String s; + private long v; // see https://github.com/web3j/web3j/issues/44 + private String type; + private String maxFeePerGas; + private String maxPriorityFeePerGas; + private List accessList; + + public TransactionCustom() {} + + public void setChainId(String chainId) { + this.chainId = chainId; + } + + public String getHash() { + return hash; + } + + public void setHash(String hash) { + this.hash = hash; + } + + public BigInteger getNonce() { + if (nonce == null) return null; + return Numeric.decodeQuantity(nonce); + } + + public void setNonce(String nonce) { + this.nonce = nonce; + } + + public String getNonceRaw() { + return nonce; + } + + public String getBlockHash() { + return blockHash; + } + + public void setBlockHash(String blockHash) { + this.blockHash = blockHash; + } + + public BigInteger getBlockNumber() { + if (blockNumber == null) return null; + return Numeric.decodeQuantity(blockNumber); + } + + public void setBlockNumber(String blockNumber) { + this.blockNumber = blockNumber; + } + + public String getBlockNumberRaw() { + return blockNumber; + } + + public BigInteger getTransactionIndex() { + if (transactionIndex == null) return null; + return Numeric.decodeQuantity(transactionIndex); + } + + public void setTransactionIndex(String transactionIndex) { + this.transactionIndex = transactionIndex; + } + + public String getTransactionIndexRaw() { + return transactionIndex; + } + + public String getFrom() { + return from; + } + + public void setFrom(String from) { + this.from = from; + } + + public String getTo() { + return to; + } + + public void setTo(String to) { + this.to = to; + } + + public BigInteger getValue() { + if (value == null) return null; + return Numeric.decodeQuantity(value); + } + + public void setValue(String value) { + this.value = value; + } + + public String getValueRaw() { + return value; + } + + public BigInteger getGasPrice() { + if (gasPrice == null) return null; + return Numeric.decodeQuantity(gasPrice); + } + + public void setGasPrice(String gasPrice) { + this.gasPrice = gasPrice; + } + + public String getGasPriceRaw() { + return gasPrice; + } + + public BigInteger getGas() { + if (gas == null) return null; + return Numeric.decodeQuantity(gas); + } + + public void setGas(String gas) { + this.gas = gas; + } + + public String getGasRaw() { + return gas; + } + + public String getInput() { + return input; + } + + public void setInput(String input) { + this.input = input; + } + + public String getCreates() { + return creates; + } + + public void setCreates(String creates) { + this.creates = creates; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public String getRaw() { + return raw; + } + + public void setRaw(String raw) { + this.raw = raw; + } + + public String getR() { + return r; + } + + public void setR(String r) { + this.r = r; + } + + public String getS() { + return s; + } + + public void setS(String s) { + this.s = s; + } + + public long getV() { + return v; + } + + // Workaround until Geth & Parity return consistent values. At present + // Parity returns a byte value, Geth returns a hex-encoded string + // https://github.com/ethereum/go-ethereum/issues/3339 + public void setV(Object v) { + if (v instanceof String) { + // longValueExact() is not implemented on android 11 or later only on 12 so it was + // replaced with longValue. + this.v = Numeric.toBigInt((String) v).longValue(); + } else if (v instanceof Integer) { + this.v = ((Integer) v).longValue(); + } else { + this.v = (Long) v; + } + } + + // public void setV(byte v) { + // this.v = v; + // } + + public Long getChainId() { + if (chainId != null) { + return Numeric.decodeQuantity(chainId).longValue(); + } + + return TransactionUtils.deriveChainId(v); + } + + public String getChainIdRaw() { + return this.chainId; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public BigInteger getMaxFeePerGas() { + if (maxFeePerGas == null) return null; + return Numeric.decodeQuantity(maxFeePerGas); + } + + public String getMaxFeePerGasRaw() { + return maxFeePerGas; + } + + public void setMaxFeePerGas(String maxFeePerGas) { + this.maxFeePerGas = maxFeePerGas; + } + + public String getMaxPriorityFeePerGasRaw() { + return maxPriorityFeePerGas; + } + + public BigInteger getMaxPriorityFeePerGas() { + if (maxPriorityFeePerGas == null) return null; + return Numeric.decodeQuantity(maxPriorityFeePerGas); + } + + public void setMaxPriorityFeePerGas(String maxPriorityFeePerGas) { + this.maxPriorityFeePerGas = maxPriorityFeePerGas; + } + + public List getAccessList() { + return accessList; + } + + public void setAccessList(List accessList) { + this.accessList = accessList; + } +}