Coverage Summary for Class: EthModuleTransactionBase (co.rsk.rpc.modules.eth)
Class |
Class, %
|
Method, %
|
Line, %
|
EthModuleTransactionBase |
100%
(1/1)
|
75%
(3/4)
|
68.8%
(33/48)
|
1 /*
2 * This file is part of RskJ
3 * Copyright (C) 2018 RSK Labs Ltd.
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 package co.rsk.rpc.modules.eth;
20
21 import co.rsk.core.RskAddress;
22 import co.rsk.core.Wallet;
23 import co.rsk.net.TransactionGateway;
24 import org.bouncycastle.util.encoders.Hex;
25 import org.ethereum.config.Constants;
26 import org.ethereum.core.*;
27 import org.ethereum.rpc.TypeConverter;
28 import org.ethereum.rpc.Web3;
29 import org.ethereum.rpc.exception.RskJsonRpcRequestException;
30 import org.ethereum.util.ByteUtil;
31 import org.ethereum.vm.GasCost;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34
35 import java.math.BigInteger;
36
37 import static org.ethereum.rpc.TypeConverter.stringHexToByteArray;
38 import static org.ethereum.rpc.exception.RskJsonRpcRequestException.invalidParamError;
39
40 public class EthModuleTransactionBase implements EthModuleTransaction {
41
42 protected static final Logger LOGGER = LoggerFactory.getLogger("web3");
43
44 private final Wallet wallet;
45 private final TransactionPool transactionPool;
46 private final Constants constants;
47 private final TransactionGateway transactionGateway;
48
49 public EthModuleTransactionBase(Constants constants, Wallet wallet, TransactionPool transactionPool, TransactionGateway transactionGateway) {
50 this.wallet = wallet;
51 this.transactionPool = transactionPool;
52 this.constants = constants;
53 this.transactionGateway = transactionGateway;
54 }
55
56 @Override
57 public synchronized String sendTransaction(Web3.CallArguments args) {
58 Account account = this.wallet.getAccount(new RskAddress(args.from));
59 String s = null;
60 try {
61 String toAddress = args.to != null ? ByteUtil.toHexString(stringHexToByteArray(args.to)) : null;
62
63 BigInteger value = args.value != null ? TypeConverter.stringNumberAsBigInt(args.value) : BigInteger.ZERO;
64 BigInteger gasPrice = args.gasPrice != null ? TypeConverter.stringNumberAsBigInt(args.gasPrice) : BigInteger.ZERO;
65 BigInteger gasLimit = args.gas != null ? TypeConverter.stringNumberAsBigInt(args.gas) : BigInteger.valueOf(GasCost.TRANSACTION_DEFAULT);
66
67 if (args.data != null && args.data.startsWith("0x")) {
68 args.data = args.data.substring(2);
69 }
70
71 synchronized (transactionPool) {
72 BigInteger accountNonce = args.nonce != null ? TypeConverter.stringNumberAsBigInt(args.nonce) : transactionPool.getPendingState().getNonce(account.getAddress());
73 Transaction tx = Transaction
74 .builder()
75 .nonce(accountNonce)
76 .gasPrice(gasPrice)
77 .gasLimit(gasLimit)
78 .destination(toAddress == null ? null : Hex.decode(toAddress))
79 .data(args.data == null ? null : Hex.decode(args.data))
80 .chainId(constants.getChainId())
81 .value(value)
82 .build();
83 tx.sign(account.getEcKey().getPrivKeyBytes());
84 TransactionPoolAddResult result = transactionGateway.receiveTransaction(tx.toImmutableTransaction());
85 if(!result.transactionsWereAdded()) {
86 throw RskJsonRpcRequestException.transactionError(result.getErrorMessage());
87 }
88
89 s = tx.getHash().toJsonString();
90 }
91
92 return s;
93
94 } finally {
95 LOGGER.debug("eth_sendTransaction({}): {}", args, s);
96 }
97 }
98
99 @Override
100 public String sendRawTransaction(String rawData) {
101 String s = null;
102 try {
103 Transaction tx = new ImmutableTransaction(stringHexToByteArray(rawData));
104
105 if (null == tx.getGasLimit()
106 || null == tx.getGasPrice()
107 || null == tx.getValue()) {
108 throw invalidParamError("Missing parameter, gasPrice, gas or value");
109 }
110
111 TransactionPoolAddResult result = transactionGateway.receiveTransaction(tx);
112 if(!result.transactionsWereAdded()) {
113 throw RskJsonRpcRequestException.transactionError(result.getErrorMessage());
114 }
115
116 return s = tx.getHash().toJsonString();
117 } finally {
118 if (LOGGER.isDebugEnabled()) {
119 LOGGER.debug("eth_sendRawTransaction({}): {}", rawData, s);
120 }
121 }
122 }
123 }