|
16 | 16 | import static org.tron.common.utils.ByteUtil.parseWord; |
17 | 17 | import static org.tron.common.utils.ByteUtil.stripLeadingZeroes; |
18 | 18 | import static org.tron.core.config.Parameter.ChainConstant.TRX_PRECISION; |
| 19 | +import static org.tron.core.vm.VMConstant.SIG_LENGTH; |
19 | 20 |
|
20 | 21 | import com.google.protobuf.ByteString; |
21 | 22 |
|
|
41 | 42 | import org.apache.commons.lang3.tuple.Triple; |
42 | 43 | import org.tron.common.crypto.Blake2bfMessageDigest; |
43 | 44 | import org.tron.common.crypto.Hash; |
| 45 | +import org.tron.common.crypto.Rsv; |
44 | 46 | import org.tron.common.crypto.SignUtils; |
45 | 47 | import org.tron.common.crypto.SignatureInterface; |
46 | 48 | import org.tron.common.crypto.zksnark.BN128; |
@@ -201,7 +203,7 @@ public class PrecompiledContracts { |
201 | 203 | public static PrecompiledContract getOptimizedContractForConstant(PrecompiledContract contract) { |
202 | 204 | try { |
203 | 205 | Constructor<?> constructor = contract.getClass().getDeclaredConstructor(); |
204 | | - return (PrecompiledContracts.PrecompiledContract) constructor.newInstance(); |
| 206 | + return (PrecompiledContracts.PrecompiledContract) constructor.newInstance(); |
205 | 207 | } catch (Exception e) { |
206 | 208 | throw new RuntimeException(e); |
207 | 209 | } |
@@ -352,22 +354,13 @@ private static byte[] encodeMultiRes(byte[]... words) { |
352 | 354 | } |
353 | 355 |
|
354 | 356 | private static byte[] recoverAddrBySign(byte[] sign, byte[] hash) { |
355 | | - byte v; |
356 | | - byte[] r; |
357 | | - byte[] s; |
358 | 357 | byte[] out = null; |
359 | 358 | if (ArrayUtils.isEmpty(sign) || sign.length < 65) { |
360 | 359 | return new byte[0]; |
361 | 360 | } |
362 | 361 | try { |
363 | | - r = Arrays.copyOfRange(sign, 0, 32); |
364 | | - s = Arrays.copyOfRange(sign, 32, 64); |
365 | | - v = sign[64]; |
366 | | - if (v < 27) { |
367 | | - v += 27; |
368 | | - } |
369 | | - |
370 | | - SignatureInterface signature = SignUtils.fromComponents(r, s, v, |
| 362 | + Rsv rsv = Rsv.fromSignature(sign); |
| 363 | + SignatureInterface signature = SignUtils.fromComponents(rsv.getR(), rsv.getS(), rsv.getV(), |
371 | 364 | CommonParameter.getInstance().isECKeyCryptoEngine()); |
372 | 365 | if (signature.validateComponents()) { |
373 | 366 | out = SignUtils.signatureToAddress(hash, signature, |
@@ -403,6 +396,20 @@ private static byte[][] extractBytesArray(DataWord[] words, int offset, byte[] d |
403 | 396 | return bytesArray; |
404 | 397 | } |
405 | 398 |
|
| 399 | + private static byte[][] extractSigArray(DataWord[] words, int offset, byte[] data) { |
| 400 | + if (offset > words.length - 1) { |
| 401 | + return new byte[0][]; |
| 402 | + } |
| 403 | + int len = words[offset].intValueSafe(); |
| 404 | + byte[][] bytesArray = new byte[len][]; |
| 405 | + for (int i = 0; i < len; i++) { |
| 406 | + int bytesOffset = words[offset + i + 1].intValueSafe() / WORD_SIZE; |
| 407 | + bytesArray[i] = extractBytes(data, (bytesOffset + offset + 2) * WORD_SIZE, |
| 408 | + SIG_LENGTH); |
| 409 | + } |
| 410 | + return bytesArray; |
| 411 | + } |
| 412 | + |
406 | 413 | private static byte[] extractBytes(byte[] data, int offset, int len) { |
407 | 414 | return Arrays.copyOfRange(data, offset, offset + len); |
408 | 415 | } |
@@ -944,8 +951,15 @@ public Pair<Boolean, byte[]> execute(byte[] rawData) { |
944 | 951 | byte[] hash = Sha256Hash.hash(CommonParameter |
945 | 952 | .getInstance().isECKeyCryptoEngine(), combine); |
946 | 953 |
|
947 | | - byte[][] signatures = extractBytesArray( |
948 | | - words, words[3].intValueSafe() / WORD_SIZE, rawData); |
| 954 | + if (VMConfig.allowTvmSelfdestructRestriction()) { |
| 955 | + int sigArraySize = words[words[3].intValueSafe() / WORD_SIZE].intValueSafe(); |
| 956 | + if (sigArraySize > MAX_SIZE) { |
| 957 | + return Pair.of(true, DATA_FALSE); |
| 958 | + } |
| 959 | + } |
| 960 | + byte[][] signatures = VMConfig.allowTvmSelfdestructRestriction() ? |
| 961 | + extractSigArray(words, words[3].intValueSafe() / WORD_SIZE, rawData) : |
| 962 | + extractBytesArray(words, words[3].intValueSafe() / WORD_SIZE, rawData); |
949 | 963 |
|
950 | 964 | if (signatures.length == 0 || signatures.length > MAX_SIZE) { |
951 | 965 | return Pair.of(true, DATA_FALSE); |
@@ -1029,8 +1043,18 @@ private Pair<Boolean, byte[]> doExecute(byte[] data) |
1029 | 1043 | throws InterruptedException, ExecutionException { |
1030 | 1044 | DataWord[] words = DataWord.parseArray(data); |
1031 | 1045 | byte[] hash = words[0].getData(); |
1032 | | - byte[][] signatures = extractBytesArray( |
1033 | | - words, words[1].intValueSafe() / WORD_SIZE, data); |
| 1046 | + |
| 1047 | + if (VMConfig.allowTvmSelfdestructRestriction()) { |
| 1048 | + int sigArraySize = words[words[1].intValueSafe() / WORD_SIZE].intValueSafe(); |
| 1049 | + int addrArraySize = words[words[2].intValueSafe() / WORD_SIZE].intValueSafe(); |
| 1050 | + if (sigArraySize > MAX_SIZE || addrArraySize > MAX_SIZE) { |
| 1051 | + return Pair.of(true, DATA_FALSE); |
| 1052 | + } |
| 1053 | + } |
| 1054 | + |
| 1055 | + byte[][] signatures = VMConfig.allowTvmSelfdestructRestriction() ? |
| 1056 | + extractSigArray(words, words[1].intValueSafe() / WORD_SIZE, data) : |
| 1057 | + extractBytesArray(words, words[1].intValueSafe() / WORD_SIZE, data); |
1034 | 1058 | byte[][] addresses = extractBytes32Array( |
1035 | 1059 | words, words[2].intValueSafe() / WORD_SIZE); |
1036 | 1060 | int cnt = signatures.length; |
|
0 commit comments