Coverage Summary for Class: ProgramInvokeFactoryImpl (org.ethereum.vm.program.invoke)
Class |
Class, %
|
Method, %
|
Line, %
|
ProgramInvokeFactoryImpl |
100%
(1/1)
|
75%
(3/4)
|
28.6%
(18/63)
|
1 /*
2 * This file is part of RskJ
3 * Copyright (C) 2017 RSK Labs Ltd.
4 * (derived from ethereumJ library, Copyright (c) 2016 <ether.camp>)
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 package org.ethereum.vm.program.invoke;
21
22 import co.rsk.core.Coin;
23 import co.rsk.core.RskAddress;
24 import org.ethereum.core.Block;
25 import org.ethereum.core.Repository;
26 import org.ethereum.core.Transaction;
27 import org.ethereum.db.BlockStore;
28 import org.ethereum.util.ByteUtil;
29 import org.ethereum.vm.DataWord;
30 import org.ethereum.vm.program.Program;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34 import java.math.BigInteger;
35
36 import static org.apache.commons.lang3.ArrayUtils.nullToEmpty;
37
38 /**
39 * @author Roman Mandeleil
40 * @since 08.06.2014
41 */
42 public class ProgramInvokeFactoryImpl implements ProgramInvokeFactory {
43
44 private static final Logger logger = LoggerFactory.getLogger("VM");
45
46 // Invocation by the wire tx
47 @Override
48 public ProgramInvoke createProgramInvoke(Transaction tx, int txindex, Block block, Repository repository,
49 BlockStore blockStore) {
50
51 /*** ADDRESS op ***/
52 // YP: Get address of currently executing account.
53 RskAddress addr = tx.isContractCreation() ? tx.getContractAddress() : tx.getReceiveAddress();
54
55 /*** ORIGIN op ***/
56 // YP: This is the sender of original transaction; it is never a contract.
57 byte[] origin = tx.getSender().getBytes();
58
59 /*** CALLER op ***/
60 // YP: This is the address of the account that is directly responsible for this execution.
61 byte[] caller = tx.getSender().getBytes();
62
63 /*** BALANCE op ***/
64 Coin balance = repository.getBalance(addr);
65
66 /*** GASPRICE op ***/
67 Coin gasPrice = tx.getGasPrice();
68
69 /*** GAS op ***/
70 byte[] gas = tx.getGasLimit();
71
72 /*** CALLVALUE op ***/
73 Coin callValue = tx.getValue();
74
75 /*** CALLDATALOAD op ***/
76 /*** CALLDATACOPY op ***/
77 /*** CALLDATASIZE op ***/
78 byte[] data = tx.isContractCreation() ? ByteUtil.EMPTY_BYTE_ARRAY : nullToEmpty(tx.getData());
79
80 /*** PREVHASH op ***/
81 byte[] lastHash = block.getParentHash().getBytes();
82
83 /*** COINBASE op ***/
84 byte[] coinbase = block.getCoinbase().getBytes();
85
86 /*** TIMESTAMP op ***/
87 long timestamp = block.getTimestamp();
88
89 /*** NUMBER op ***/
90 long number = block.getNumber();
91
92 /*** DIFFICULTY op ***/
93 byte[] difficulty = block.getDifficulty().getBytes();
94
95 /*** GASLIMIT op ***/
96 byte[] gaslimit = block.getGasLimit();
97
98 if (logger.isInfoEnabled()) {
99 logger.info("Top level call: \n" +
100 "address={}\n" +
101 "origin={}\n" +
102 "caller={}\n" +
103 "balance={}\n" +
104 "gasPrice={}\n" +
105 "gas={}\n" +
106 "callValue={}\n" +
107 "data={}\n" +
108 "lastHash={}\n" +
109 "coinbase={}\n" +
110 "timestamp={}\n" +
111 "blockNumber={}\n" +
112 "transactionIndex={}\n" +
113 "difficulty={}\n" +
114 "gaslimit={}\n",
115
116 addr,
117 ByteUtil.toHexString(origin),
118 ByteUtil.toHexString(caller),
119 balance,
120 gasPrice,
121 new BigInteger(1, gas).longValue(),
122 callValue,
123 ByteUtil.toHexString(data),
124 ByteUtil.toHexString(lastHash),
125 ByteUtil.toHexString(coinbase),
126 timestamp,
127 number,
128 txindex,
129 ByteUtil.toHexString(difficulty),
130 gaslimit);
131 }
132
133 return new ProgramInvokeImpl(addr.getBytes(), origin, caller, balance.getBytes(), gasPrice.getBytes(), gas, callValue.getBytes(), data,
134 lastHash, coinbase, timestamp, number, txindex,difficulty, gaslimit,
135 repository, blockStore);
136 }
137
138 /**
139 * This invocation created for contract call contract
140 */
141 @Override
142 public ProgramInvoke createProgramInvoke(Program program, DataWord toAddress, DataWord callerAddress,
143 DataWord inValue,
144 long inGas,
145 Coin balanceInt, byte[] dataIn,
146 Repository repository, BlockStore blockStore,
147 boolean isStaticCall, boolean byTestingSuite) {
148
149 DataWord address = toAddress;
150 DataWord origin = program.getOriginAddress();
151 DataWord caller = callerAddress;
152
153 DataWord balance = DataWord.valueOf(balanceInt.getBytes());
154 DataWord gasPrice = program.getGasPrice();
155 long agas = inGas;
156 DataWord callValue = inValue;
157
158 byte[] data = dataIn;
159 DataWord lastHash = program.getPrevHash();
160 DataWord coinbase = program.getCoinbase();
161 DataWord timestamp = program.getTimestamp();
162 DataWord number = program.getNumber();
163 DataWord transactionIndex = program.getTransactionIndex();
164 DataWord difficulty = program.getDifficulty();
165 DataWord gasLimit = program.getGasLimit();
166
167 if (logger.isInfoEnabled()) {
168 logger.info("Internal call: \n" +
169 "address={}\n" +
170 "origin={}\n" +
171 "caller={}\n" +
172 "balance={}\n" +
173 "gasPrice={}\n" +
174 "gas={}\n" +
175 "callValue={}\n" +
176 "data={}\n" +
177 "lastHash={}\n" +
178 "coinbase={}\n" +
179 "timestamp={}\n" +
180 "blockNumber={}\n" +
181 "transactionIndex={}\n" +
182 "difficulty={}\n" +
183 "gaslimit={}\n",
184 ByteUtil.toHexString(address.getLast20Bytes()),
185 ByteUtil.toHexString(origin.getLast20Bytes()),
186 ByteUtil.toHexString(caller.getLast20Bytes()),
187 balance.toString(),
188 gasPrice.longValue(),
189 agas,
190 ByteUtil.toHexString(callValue.getNoLeadZeroesData()),
191 data == null ? "" : ByteUtil.toHexString(data),
192 ByteUtil.toHexString(lastHash.getData()),
193 ByteUtil.toHexString(coinbase.getLast20Bytes()),
194 timestamp.longValue(),
195 number.longValue(),
196 transactionIndex.intValue(),
197 ByteUtil.toHexString(difficulty.getNoLeadZeroesData()),
198 gasLimit.bigIntValue());
199 }
200
201 return new ProgramInvokeImpl(address, origin, caller, balance, gasPrice, agas, callValue,
202 data, lastHash, coinbase, timestamp, number, transactionIndex, difficulty, gasLimit,
203 repository, program.getCallDeep() + 1, blockStore,
204 isStaticCall, byTestingSuite);
205 }
206 }