diff --git a/rskj-core/src/main/java/co/rsk/core/bc/ClaimTransactionValidator.java b/rskj-core/src/main/java/co/rsk/core/bc/ClaimTransactionValidator.java index 30a6f04d43d..b0f97061e79 100644 --- a/rskj-core/src/main/java/co/rsk/core/bc/ClaimTransactionValidator.java +++ b/rskj-core/src/main/java/co/rsk/core/bc/ClaimTransactionValidator.java @@ -90,25 +90,28 @@ public byte[] encodePacked(Object...arguments) { byte[] encodedArguments = new byte[]{}; for(Object arg: arguments) { - byte[] encodedArg = new byte[]{}; - if(arg instanceof byte[]) { - SolidityType bytes32Type = SolidityType.getType(SolidityType.BYTES32); - encodedArg = bytes32Type.encode(arg); - } else if(arg instanceof RskAddress) { - SolidityType addressType = SolidityType.getType(SolidityType.ADDRESS); - byte[] encodedAddress = addressType.encode(((RskAddress) arg).toHexString()); - encodedArg = org.bouncycastle.util.Arrays.copyOfRange(encodedAddress, 12, encodedAddress.length); - } else if(arg instanceof BigInteger) { - SolidityType uint256Type = SolidityType.getType(SolidityType.UINT); - encodedArg = uint256Type.encode(arg); - } - + byte[] encodedArg = encodeArgumentAccordingInstanceType(arg); encodedArguments = ByteUtil.merge(encodedArguments, encodedArg); } return encodedArguments; } + private static byte[] encodeArgumentAccordingInstanceType(Object arg) { + if (arg instanceof byte[]) { + SolidityType bytes32Type = SolidityType.getType(SolidityType.BYTES32); + return bytes32Type.encode(arg); + } else if (arg instanceof RskAddress) { + SolidityType addressType = SolidityType.getType(SolidityType.ADDRESS); + byte[] encodedAddress = addressType.encode(((RskAddress) arg).toHexString()); + return org.bouncycastle.util.Arrays.copyOfRange(encodedAddress, 12, encodedAddress.length); + } else if (arg instanceof BigInteger) { + SolidityType uint256Type = SolidityType.getType(SolidityType.UINT); + return uint256Type.encode(arg); + } + return new byte[]{}; + } + public boolean isClaimTx(Transaction tx) { return tx.getReceiveAddress() != null && tx.getData() != null diff --git a/rskj-core/src/main/java/org/ethereum/config/blockchain/upgrades/ConsensusRule.java b/rskj-core/src/main/java/org/ethereum/config/blockchain/upgrades/ConsensusRule.java index 857e406bcf4..792e9da75e6 100644 --- a/rskj-core/src/main/java/org/ethereum/config/blockchain/upgrades/ConsensusRule.java +++ b/rskj-core/src/main/java/org/ethereum/config/blockchain/upgrades/ConsensusRule.java @@ -93,13 +93,9 @@ public enum ConsensusRule { RSKIP412("rskip412"), // From EIP-3198 BASEFEE opcode RSKIP415("rskip415"), RSKIP417("rskip417"), -<<<<<<< HEAD RSKIP428("rskip428"), RSKIP434("rskip434"), - RSKIP00("rskip00") // Placeholder for EthSwap feature -======= RSKIP432("rskip432"), // From RSKIP-432 RbtcSwap ->>>>>>> bd8b9a1a4 (Add RSKIP number and refactor validate method in TxValidatorStep) ; private String configKey; diff --git a/rskj-core/src/test/java/co/rsk/util/ClaimTransactionValidatorTest.java b/rskj-core/src/test/java/co/rsk/util/ClaimTransactionValidatorTest.java index 76465339c43..d9d1699ccbb 100644 --- a/rskj-core/src/test/java/co/rsk/util/ClaimTransactionValidatorTest.java +++ b/rskj-core/src/test/java/co/rsk/util/ClaimTransactionValidatorTest.java @@ -53,7 +53,7 @@ void setup() { @Test public void whenIsClaimTxAndValidIsCalled_shouldReturnTrue() { - Transaction mockedClaimTx = createClaimTx(10, "preimage".getBytes(StandardCharsets.UTF_8), 0); + Transaction mockedClaimTx = createClaimTx(10, "preimage".getBytes(StandardCharsets.UTF_8), 0, 5); RepositorySnapshot mockedRepository = mock(RepositorySnapshot.class); ActivationConfig.ForBlock mockedActivationConfig = mock(ActivationConfig.ForBlock.class); @@ -70,12 +70,30 @@ public void whenIsClaimTxAndValidIsCalled_shouldReturnTrue() { assertTrue(result); } + @Test + public void whenIsClaimTxAndValidIsCalled_withInsufficientFunds_shouldReturnFalse() { + Transaction mockedClaimTx = createClaimTx(10, "preimage".getBytes(StandardCharsets.UTF_8), 0, 12); + RepositorySnapshot mockedRepository = mock(RepositorySnapshot.class); + ActivationConfig.ForBlock mockedActivationConfig = mock(ActivationConfig.ForBlock.class); + + when(mockedRepository.getBalance(any(RskAddress.class))).thenReturn(Coin.valueOf(1)); + + when(mockedRepository.getStorageValue(eq(mockedClaimTx.getReceiveAddress()), any(DataWord.class))) + .thenReturn(DataWord.valueOf(1)); + when(mockedActivationConfig.isActive(ConsensusRule.RSKIP432)).thenReturn(true); + + boolean result = claimTransactionValidator.isClaimTxAndValid(mockedClaimTx, mockedRepository, mockedActivationConfig); + + assertFalse(result); + } + + @Test public void whenIsClaimTxAndSenderCanPayAlongPendingTxIsCalled_withIdenticalNewAndPendingTx_shouldReturnFalse() { - Transaction mockedClaimTx = createClaimTx(10, "preimage".getBytes(StandardCharsets.UTF_8), 0); + Transaction mockedClaimTx = createClaimTx(10, "preimage".getBytes(StandardCharsets.UTF_8), 0, 5); List pendingTransactions = new ArrayList<>(); - pendingTransactions.add(createClaimTx(10, "preimage".getBytes(StandardCharsets.UTF_8), 1)); + pendingTransactions.add(createClaimTx(10, "preimage".getBytes(StandardCharsets.UTF_8), 1, 5)); SignatureCache signatureCache = new ReceivedTxSignatureCache(); RepositorySnapshot mockedRepository = mock(RepositorySnapshot.class); @@ -90,8 +108,8 @@ public void whenIsClaimTxAndSenderCanPayAlongPendingTxIsCalled_withIdenticalNewA @Test public void whenIsClaimTxAndSenderCanPayAlongPendingTxIsCalled_withMultipleClaimTx_shouldCombineLockedAmounts() { - Transaction mockedClaimTx = createClaimTx(3, "test".getBytes(StandardCharsets.UTF_8), 0); - Transaction mockedPendingClaimTx = createClaimTx(10, "preimage".getBytes(StandardCharsets.UTF_8), 1); + Transaction mockedClaimTx = createClaimTx(3, "test".getBytes(StandardCharsets.UTF_8), 0, 5); + Transaction mockedPendingClaimTx = createClaimTx(10, "preimage".getBytes(StandardCharsets.UTF_8), 1, 5); List pendingTransactions = new ArrayList<>(); pendingTransactions.add(mockedPendingClaimTx); @@ -110,7 +128,7 @@ public void whenIsClaimTxAndSenderCanPayAlongPendingTxIsCalled_withMultipleClaim assertTrue(result); } - private Transaction createClaimTx(int amount, byte[] preimage, long nonce) { + private Transaction createClaimTx(int amount, byte[] preimage, long nonce, int gasLimit) { byte[] senderBytes = Hex.decode("0000000000000000000000000000000001000001"); RskAddress claimAddress = new RskAddress(senderBytes); @@ -125,7 +143,7 @@ private Transaction createClaimTx(int amount, byte[] preimage, long nonce) { when(claimTx.getSender(any(SignatureCache.class))).thenReturn(claimAddress); when(claimTx.getNonce()).thenReturn(BigInteger.valueOf(nonce).toByteArray()); when(claimTx.getGasPrice()).thenReturn(Coin.valueOf(1)); - when(claimTx.getGasLimit()).thenReturn(BigInteger.valueOf(5).toByteArray()); + when(claimTx.getGasLimit()).thenReturn(BigInteger.valueOf(gasLimit).toByteArray()); when(claimTx.getReceiveAddress()).thenReturn(new RskAddress(testConstants.getEtherSwapContractAddress())); when(claimTx.getData()).thenReturn(callData); when(claimTx.getValue()).thenReturn(Coin.ZERO);