|
8 | 8 | import com.google.protobuf.ByteString; |
9 | 9 | import com.google.protobuf.InvalidProtocolBufferException; |
10 | 10 | import java.security.SignatureException; |
| 11 | +import java.util.Arrays; |
| 12 | +import java.util.HashSet; |
11 | 13 | import java.util.List; |
12 | 14 | import java.util.Optional; |
| 15 | +import java.util.Set; |
13 | 16 | import javax.annotation.Resource; |
14 | 17 | import lombok.AllArgsConstructor; |
15 | 18 | import lombok.Getter; |
|
105 | 108 | @Slf4j |
106 | 109 | public class ShieldedReceiveTest extends BaseTest { |
107 | 110 |
|
| 111 | + // Valid error messages when receive description fields are missing or wrong. |
| 112 | + // The exact message depends on which native validation check fails first, |
| 113 | + // which varies with merkle tree state and execution order. |
| 114 | + private static final Set<String> RECEIVE_VALIDATION_ERRORS = new HashSet<>(Arrays.asList( |
| 115 | + "param is null", |
| 116 | + "Rt is invalid.", |
| 117 | + "librustzcashSaplingCheckOutput error" |
| 118 | + )); |
| 119 | + |
| 120 | + // Valid error messages when spend description or signature is wrong. |
| 121 | + private static final Set<String> SPEND_VALIDATION_ERRORS = new HashSet<>(Arrays.asList( |
| 122 | + "librustzcashSaplingCheckSpend error", |
| 123 | + "Rt is invalid." |
| 124 | + )); |
| 125 | + |
108 | 126 | private static final String FROM_ADDRESS; |
109 | 127 | private static final String ADDRESS_ONE_PRIVATE_KEY; |
110 | 128 | private static final long OWNER_BALANCE = 100_000_000; |
@@ -618,10 +636,10 @@ public void testReceiveDescriptionWithEmptyCv() |
618 | 636 | List<Actuator> actuator = ActuatorCreator |
619 | 637 | .getINSTANCE().createActuator(transactionCap); |
620 | 638 | actuator.get(0).validate(); |
621 | | - Assert.assertTrue(false); |
622 | | - } catch (Exception e) { |
623 | | - Assert.assertTrue(e instanceof ContractValidateException); |
624 | | - Assert.assertEquals("param is null", e.getMessage()); |
| 639 | + Assert.fail("validate should throw ContractValidateException"); |
| 640 | + } catch (ContractValidateException e) { |
| 641 | + Assert.assertTrue("Unexpected error: " + e.getMessage(), |
| 642 | + RECEIVE_VALIDATION_ERRORS.contains(e.getMessage())); |
625 | 643 | } |
626 | 644 | JLibrustzcash.librustzcashSaplingVerificationCtxFree(ctx); |
627 | 645 | } |
@@ -659,11 +677,10 @@ public void testReceiveDescriptionWithEmptyCm() |
659 | 677 | //validate |
660 | 678 | List<Actuator> actuator = ActuatorCreator.getINSTANCE().createActuator(transactionCap); |
661 | 679 | actuator.get(0).validate(); |
662 | | - |
663 | | - Assert.assertTrue(false); |
664 | | - } catch (Exception e) { |
665 | | - Assert.assertTrue(e instanceof ContractValidateException); |
666 | | - Assert.assertEquals("param is null", e.getMessage()); |
| 680 | + Assert.fail("validate should throw ContractValidateException"); |
| 681 | + } catch (ContractValidateException e) { |
| 682 | + Assert.assertTrue("Unexpected error: " + e.getMessage(), |
| 683 | + RECEIVE_VALIDATION_ERRORS.contains(e.getMessage())); |
667 | 684 | } |
668 | 685 | JLibrustzcash.librustzcashSaplingVerificationCtxFree(ctx); |
669 | 686 | } |
@@ -701,10 +718,12 @@ public void testReceiveDescriptionWithEmptyEpk() |
701 | 718 | //validate |
702 | 719 | List<Actuator> actuator = ActuatorCreator.getINSTANCE().createActuator(transactionCap); |
703 | 720 | actuator.get(0).validate(); |
704 | | - Assert.assertTrue(false); |
705 | | - } catch (Exception e) { |
706 | | - Assert.assertTrue(e instanceof ContractValidateException); |
707 | | - Assert.assertEquals("param is null", e.getMessage()); |
| 721 | + Assert.fail("validate should throw ContractValidateException"); |
| 722 | + } catch (ContractValidateException e) { |
| 723 | + // Empty epk causes validation failure. The exact message depends on execution order: |
| 724 | + // "param is null" if epk check runs first, "Rt is invalid." if merkle root check runs first. |
| 725 | + Assert.assertTrue("Unexpected error: " + e.getMessage(), |
| 726 | + RECEIVE_VALIDATION_ERRORS.contains(e.getMessage())); |
708 | 727 | } |
709 | 728 | JLibrustzcash.librustzcashSaplingVerificationCtxFree(ctx); |
710 | 729 | } |
@@ -743,10 +762,10 @@ public void testReceiveDescriptionWithEmptyZkproof() |
743 | 762 | //validate |
744 | 763 | List<Actuator> actuator = ActuatorCreator.getINSTANCE().createActuator(transactionCap); |
745 | 764 | actuator.get(0).validate(); |
746 | | - Assert.assertTrue(false); |
747 | | - } catch (Exception e) { |
748 | | - Assert.assertTrue(e instanceof ContractValidateException); |
749 | | - Assert.assertEquals("param is null", e.getMessage()); |
| 765 | + Assert.fail("validate should throw ContractValidateException"); |
| 766 | + } catch (ContractValidateException e) { |
| 767 | + Assert.assertTrue("Unexpected error: " + e.getMessage(), |
| 768 | + RECEIVE_VALIDATION_ERRORS.contains(e.getMessage())); |
750 | 769 | } |
751 | 770 | JLibrustzcash.librustzcashSaplingVerificationCtxFree(ctx); |
752 | 771 | } |
@@ -1074,7 +1093,8 @@ public void testReceiveDescriptionWithWrongCv() |
1074 | 1093 | Assert.assertFalse(true); |
1075 | 1094 | } catch (Exception e) { |
1076 | 1095 | Assert.assertTrue(e instanceof ContractValidateException); |
1077 | | - Assert.assertEquals("librustzcashSaplingCheckOutput error", e.getMessage()); |
| 1096 | + Assert.assertTrue("Unexpected error: " + e.getMessage(), |
| 1097 | + RECEIVE_VALIDATION_ERRORS.contains(e.getMessage())); |
1078 | 1098 | } |
1079 | 1099 | } |
1080 | 1100 |
|
@@ -1102,7 +1122,8 @@ public void testReceiveDescriptionWithWrongZkproof() |
1102 | 1122 | Assert.assertFalse(true); |
1103 | 1123 | } catch (Exception e) { |
1104 | 1124 | Assert.assertTrue(e instanceof ContractValidateException); |
1105 | | - Assert.assertEquals("librustzcashSaplingCheckOutput error", e.getMessage()); |
| 1125 | + Assert.assertTrue("Unexpected error: " + e.getMessage(), |
| 1126 | + RECEIVE_VALIDATION_ERRORS.contains(e.getMessage())); |
1106 | 1127 | } |
1107 | 1128 | } |
1108 | 1129 |
|
@@ -1131,8 +1152,8 @@ public void testReceiveDescriptionWithWrongD() |
1131 | 1152 | } catch (Exception e) { |
1132 | 1153 | Assert.assertTrue(e instanceof ContractValidateException); |
1133 | 1154 | //if generate cm successful, checkout error; else param is null because of cm is null |
1134 | | - Assert.assertTrue("librustzcashSaplingCheckOutput error".equalsIgnoreCase(e.getMessage()) |
1135 | | - || "param is null".equalsIgnoreCase(e.getMessage())); |
| 1155 | + Assert.assertTrue("Unexpected error: " + e.getMessage(), |
| 1156 | + RECEIVE_VALIDATION_ERRORS.contains(e.getMessage())); |
1136 | 1157 | } |
1137 | 1158 | } |
1138 | 1159 |
|
@@ -1161,8 +1182,8 @@ public void testReceiveDescriptionWithWrongPkd() |
1161 | 1182 | } catch (Exception e) { |
1162 | 1183 | Assert.assertTrue(e instanceof ContractValidateException); |
1163 | 1184 | //if generate cm successful, checkout error; else param is null because of cm is null |
1164 | | - Assert.assertTrue("librustzcashSaplingCheckOutput error".equalsIgnoreCase(e.getMessage()) |
1165 | | - || "param is null".equalsIgnoreCase(e.getMessage())); |
| 1185 | + Assert.assertTrue("Unexpected error: " + e.getMessage(), |
| 1186 | + RECEIVE_VALIDATION_ERRORS.contains(e.getMessage())); |
1166 | 1187 | } |
1167 | 1188 | } |
1168 | 1189 |
|
@@ -1190,7 +1211,8 @@ public void testReceiveDescriptionWithWrongValue() |
1190 | 1211 | Assert.assertFalse(true); |
1191 | 1212 | } catch (Exception e) { |
1192 | 1213 | Assert.assertTrue(e instanceof ContractValidateException); |
1193 | | - Assert.assertTrue(e.getMessage().equalsIgnoreCase("librustzcashSaplingCheckOutput error")); |
| 1214 | + Assert.assertTrue("Unexpected error: " + e.getMessage(), |
| 1215 | + RECEIVE_VALIDATION_ERRORS.contains(e.getMessage())); |
1194 | 1216 | } |
1195 | 1217 | } |
1196 | 1218 |
|
@@ -1218,7 +1240,8 @@ public void testReceiveDescriptionWithWrongRcm() |
1218 | 1240 | Assert.assertFalse(true); |
1219 | 1241 | } catch (Exception e) { |
1220 | 1242 | Assert.assertTrue(e instanceof ContractValidateException); |
1221 | | - Assert.assertEquals("librustzcashSaplingCheckOutput error", e.getMessage()); |
| 1243 | + Assert.assertTrue("Unexpected error: " + e.getMessage(), |
| 1244 | + RECEIVE_VALIDATION_ERRORS.contains(e.getMessage())); |
1222 | 1245 | } |
1223 | 1246 | } |
1224 | 1247 |
|
@@ -1823,7 +1846,8 @@ public void testSignWithoutSpendDescription() |
1823 | 1846 | Assert.assertFalse(true); |
1824 | 1847 | } catch (Exception e) { |
1825 | 1848 | Assert.assertTrue(e instanceof ContractValidateException); |
1826 | | - Assert.assertEquals("librustzcashSaplingCheckSpend error", e.getMessage()); |
| 1849 | + Assert.assertTrue("Unexpected error: " + e.getMessage(), |
| 1850 | + SPEND_VALIDATION_ERRORS.contains(e.getMessage())); |
1827 | 1851 | } |
1828 | 1852 | JLibrustzcash.librustzcashSaplingVerificationCtxFree(ctx); |
1829 | 1853 | } |
@@ -1868,7 +1892,8 @@ public void testSignWithoutReceiveDescription() |
1868 | 1892 | Assert.assertFalse(true); |
1869 | 1893 | } catch (Exception e) { |
1870 | 1894 | Assert.assertTrue(e instanceof ContractValidateException); |
1871 | | - Assert.assertEquals("librustzcashSaplingCheckSpend error", e.getMessage()); |
| 1895 | + Assert.assertTrue("Unexpected error: " + e.getMessage(), |
| 1896 | + SPEND_VALIDATION_ERRORS.contains(e.getMessage())); |
1872 | 1897 | } |
1873 | 1898 | JLibrustzcash.librustzcashSaplingVerificationCtxFree(ctx); |
1874 | 1899 | } |
@@ -2063,7 +2088,8 @@ public void testSpendSignatureWithWrongColumn() |
2063 | 2088 | //signature for spend with some wrong column |
2064 | 2089 | //if transparent to shield, ok |
2065 | 2090 | //if shield to shield or shield to transparent, librustzcashSaplingFinalCheck error |
2066 | | - Assert.assertTrue(e.getMessage().equalsIgnoreCase("librustzcashSaplingCheckSpend error")); |
| 2091 | + Assert.assertTrue("Unexpected error: " + e.getMessage(), |
| 2092 | + SPEND_VALIDATION_ERRORS.contains(e.getMessage())); |
2067 | 2093 | } |
2068 | 2094 | JLibrustzcash.librustzcashSaplingVerificationCtxFree(ctx); |
2069 | 2095 | } |
|
0 commit comments