From 0fd2f715bbe9d45a81bc6163cc24f25447dadbf3 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Sat, 27 Sep 2025 03:04:04 -0400 Subject: [PATCH 1/6] switch `fixIncludeKeyletFields` to `Supported::yes` (#5819) --- include/xrpl/protocol/detail/features.macro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/xrpl/protocol/detail/features.macro b/include/xrpl/protocol/detail/features.macro index ce9583dace..d25d33b663 100644 --- a/include/xrpl/protocol/detail/features.macro +++ b/include/xrpl/protocol/detail/features.macro @@ -32,7 +32,7 @@ // If you add an amendment here, then do not forget to increment `numFeatures` // in include/xrpl/protocol/Feature.h. -XRPL_FIX (IncludeKeyletFields, Supported::no, VoteBehavior::DefaultNo) +XRPL_FIX (IncludeKeyletFields, Supported::yes, VoteBehavior::DefaultNo) XRPL_FEATURE(DynamicMPT, Supported::no, VoteBehavior::DefaultNo) XRPL_FIX (TokenEscrowV1, Supported::yes, VoteBehavior::DefaultNo) XRPL_FIX (DelegateV1_1, Supported::no, VoteBehavior::DefaultNo) From 57fc1df7d7cf35f3711a6e37726535899813bf24 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Mon, 29 Sep 2025 15:43:22 -0400 Subject: [PATCH 2/6] switch from wasm32-unknown-unknown to wasm32v1-none (#5814) --- src/test/app/Wasm_test.cpp | 2 +- src/test/app/wasm_fixtures/copyFixtures.py | 6 +- src/test/app/wasm_fixtures/fixtures.cpp | 1084 ++++++++++---------- 3 files changed, 529 insertions(+), 563 deletions(-) diff --git a/src/test/app/Wasm_test.cpp b/src/test/app/Wasm_test.cpp index 4348e14130..2b1259365a 100644 --- a/src/test/app/Wasm_test.cpp +++ b/src/test/app/Wasm_test.cpp @@ -519,7 +519,7 @@ struct Wasm_test : public beast::unit_test::suite if (BEAST_EXPECT(re.has_value())) { BEAST_EXPECTS(re->result == 1, std::to_string(re->result)); - BEAST_EXPECTS(re->cost == 96'942, std::to_string(re->cost)); + BEAST_EXPECTS(re->cost == 97'411, std::to_string(re->cost)); } env.close(); } diff --git a/src/test/app/wasm_fixtures/copyFixtures.py b/src/test/app/wasm_fixtures/copyFixtures.py index b0c8ad1af2..cd53184b5e 100644 --- a/src/test/app/wasm_fixtures/copyFixtures.py +++ b/src/test/app/wasm_fixtures/copyFixtures.py @@ -46,10 +46,10 @@ def process_rust(project_name): project_path = os.path.abspath( os.path.join(os.path.dirname(__file__), project_name) ) - wasm_location = f"target/wasm32-unknown-unknown/release/{project_name}.wasm" + wasm_location = f"target/wasm32v1-none/release/{project_name}.wasm" build_cmd = ( f"(cd {project_path} " - f"&& cargo build --target wasm32-unknown-unknown --release " + f"&& cargo build --target wasm32v1-none --release " f"&& wasm-opt {wasm_location} {OPT} -o {wasm_location}" ")" ) @@ -68,7 +68,7 @@ def process_rust(project_name): src_path = os.path.abspath( os.path.join( os.path.dirname(__file__), - f"{project_name}/target/wasm32-unknown-unknown/release/{project_name}.wasm", + f"{project_name}/target/wasm32v1-none/release/{project_name}.wasm", ) ) with open(src_path, "rb") as f: diff --git a/src/test/app/wasm_fixtures/fixtures.cpp b/src/test/app/wasm_fixtures/fixtures.cpp index 8fb6340bed..6ad3e33639 100644 --- a/src/test/app/wasm_fixtures/fixtures.cpp +++ b/src/test/app/wasm_fixtures/fixtures.cpp @@ -8659,196 +8659,195 @@ extern std::string const allHostFunctionsWasmHex = "08686f73745f6c69620b7570646174655f64617461000103060506060a0b04050301001106" "19037f01418080c0000b7f0041af99c0000b7f0041b099c0000b072e04066d656d6f727902" "000666696e697368001e0a5f5f646174615f656e6403010b5f5f686561705f626173650302" - "0a801c051900200241094f0440000b20002002360204200020013602000b1900200241214f" + "0aff1b051900200241094f0440000b20002002360204200020013602000b1900200241214f" "0440000b20002002360204200020013602000b970101057f230041206b2201240020014118" "6a22044100360200200141106a220542003703002001420037030802404181802020014108" "6a4114100022034114470440024020034100480440200020033602040c010b2000417f3602" "040b410121020c010b20002001290308370001200041116a2004280200360000200041096a" - "20052903003700000b200020023a0000200141206a24000b450020012d0000450440200020" - "01290001370000200041106a200141116a280000360000200041086a200141096a29000037" - "00000f0b418080c000410b20013402041001000bea1901097f230041b0036b22002400418b" - "80c000411b41004100410010021a41a680c000411941004100410010021a41e780c000412b" - "41004100410010021a027f02400240024002400240024002401003220141004a0440419281" - "c00041172001ad10011a1004220141004c0d0141a981c00041132001ad10011a200041c801" - "6a22034200370300200041c0016a22054200370300200041b8016a22044200370300200042" - "003703b001200041b0016a22064120100522014120470d0241bc81c0004113200641204101" - "10021a41cf81c000412041004100410010021a41dc82c000412e41004100410010021a2000" - "41a0016a410036020020004198016a42003703002000420037039001418180202000419001" - "6a22024114100022014114470d03418a83c00041142002411410061a200042003703704188" - "8018200041f0006a22024108100022014108470d04419e83c0004117420810011a41b583c0" - "00412820024108410110021a2000410036025041848008200041d0006a2202410410002201" - "4104470d0541dd83c000411520024104410110021a200041013b003c200342003703002005" - "420037030020044200370300200042003703b00102402000413c6a41022006412010072201" - "41004e044041f283c00041142001ad10011a200041306a20062001101b418684c000410d20" - "002802302000280234410110021a0c010b419384c00041292001ac10011a0b41bc84c00041" - "154183803c1008ac10011a41d184c00041134189803c1008ac10011a02402000413c6a4102" - "1009220141004e044041e484c00041142001ad10011a0c010b41f884c000412d2001ac1001" - "1a0b41a585c000412341004100410010021a41de86c000413341004100410010021a200042" - "0037037041828018200041f0006a22014108100a220241004c0d0620024108460440419187" - "c000412b420810011a41bc87c000412f20014108410110021a0c080b41eb87c000412f2002" - "ad10011a200041286a200041f0006a2002101a419a88c00041172000280228200028022c41" - "0110021a0c070b41bf82c000411d2001ac10011a419b7f0c070b419a82c00041252001ac10" - "011a419a7f0c060b41ef81c000412b2001ac10011a41997f0c050b41b486c000412a2001ac" - "10011a41b77e0c040b41f385c00041c1002001ac10011a41b67e0c030b41c885c000412b20" - "01ac10011a41b57e0c020b41b188c00041c5002002ac10011a0b200041a0016a4100360200" - "20004198016a4200370300200042003703900102404181802020004190016a22024114100a" - "220141004a044041f688c000411e2002411410061a0c010b419489c00041332001ac10011a" - "0b200041013b0050200041c8016a4200370300200041c0016a4200370300200041b8016a42" - "00370300200042003703b0010240200041d0006a4102200041b0016a22014120100b220241" - "004e044041c789c000411c2002ad10011a200041206a20012002101b41e389c00041152000" - "2802202000280224410110021a0c010b41f889c00041392002ac10011a0b41b18ac0004124" - "4183803c100cac10011a0240200041d0006a4102100d220141004e044041d58ac000411c20" - "01ad10011a0c010b41f18ac000413d2001ac10011a0b41ae8bc00041284100410041001002" - "1a41d68bc000412f41004100410010021a200041b0016a2202101c200041f0006a22012002" - "101d200041a8016a4200370300200041a0016a420037030020004198016a42003703002000" - "420037039001024002400240024002402001411420004190016a22024120100e2201412046" - "0440200241204100100f220441004a044041858cc00041232004ad10011a20004200370350" - "200441828018200041d0006a220141081010220241004c0d022002410846044041a88cc000" - "412a420810011a41d28cc000412e20014108410110021a0c060b41808dc000412e2002ad10" - "011a200041186a200041d0006a2002101a41ae8dc00041162000280218200028021c410110" - "021a0c050b41e68fc000413c2004ac10011a200041c8016a4200370300200041c0016a4200" - "370300200041b8016a4200370300200042003703b001410141828018200041b0016a412010" - "1022014100480d020c030b41ba92c000412e2001ac10011a41ef7c0c050b41c48dc000412b" - "2002ac10011a0c020b41a290c00041c1002001ac10011a0b200041013b00504101200041d0" - "006a4102200041b0016a412010112201410048044041e390c00041352001ac10011a0b4101" - "4183803c101222014100480440419891c00041322001ac10011a0b4101200041d0006a4102" - "10132201410048044041ca91c00041392001ac10011a0b418392c000413741004100410010" - "021a0c010b200041013b003c200041c8016a4200370300200041c0016a4200370300200041" - "b8016a4200370300200042003703b001024020042000413c6a4102200041b0016a22014120" - "1011220241004e044041ef8dc000411b2002ad10011a200041106a20012002101b418a8ec0" - "00411420002802102000280214410110021a0c010b419e8ec00041312002ac10011a0b41cf" - "8ec000412320044183803c1012ac10011a024020042000413c6a41021013220141004e0440" - "41f28ec000411b2001ad10011a0c010b418d8fc00041352001ac10011a0b41c28fc0004124" - "41004100410010021a0b41e892c000412f41004100410010021a200041b0016a2201101c20" - "00413c6a22042001101d200041e8006a4200370300200041e0006a4200370300200041d800" - "6a42003703002000420037035002400240024002400240024020044114200041d0006a2202" - "4120100e22014120460440419793c000410f20024120410110021a20004188016a42003703" - "0020004180016a4200370300200041f8006a42003703002000420037037002402004411420" - "04411441a693c0004109200041f0006a220141201014220241004a0440200041086a200120" - "02101b41ae93c00041122000280208200028020c410110021a0c010b41c093c000413c2002" - "ac10011a0b200041a8016a22084200370300200041a0016a2203420037030020004198016a" - "2205420037030020004200370390012000413c6a2202411441e80720004190016a22074120" - "101522014120470d0141fc93c000410e20074120410110021a200041c8016a420037030020" - "0041c0016a4200370300200041b8016a4200370300200042003703b00120024114412a2000" - "41b0016a22044120101622014120470d02418a94c000410e20044120410110021a419894c0" - "00412441004100410010021a419195c000412541004100410010021a20004188016a420037" - "030020004180016a4200370300200041f8006a42003703002000420037037041b695c00041" - "17200041f0006a22024120101722014120470d0341cd95c000410b41b695c0004117410110" - "021a41d895c000411120024120410110021a2004101c200041d0006a22062004101d200842" - "00370300200342003703002005420037030020004200370390010240200422032003410020" - "036b41037122026a22054f0d0020020440200221010340200341003a0000200341016a2103" - "200141016b22010d000b0b200241016b4107490d000340200341003a0000200341076a4100" - "3a0000200341066a41003a0000200341056a41003a0000200341046a41003a000020034103" - "6a41003a0000200341026a41003a0000200341016a41003a0000200341086a22032005470d" - "000b0b200541800220026b2201417c716a220320054b044003402005410036020020054104" - "6a22052003490d000b0b024020032001410371220120036a22024f0d002001220504400340" - "200341003a0000200341016a2103200541016b22050d000b0b200141016b4107490d000340" - "200341003a0000200341076a41003a0000200341066a41003a0000200341056a41003a0000" - "200341046a41003a0000200341036a41003a0000200341026a41003a0000200341016a4100" - "3a0000200341086a22032002470d000b0b0240200641142007412020044180021018220141" - "004a044041e995c00041102001ad10011a20014181024f0d0641f995c00041092004200141" - "0110021a0c010b418296c000412e2001ac10011a0b41b096c000411241c296c00041074101" - "100222014100480d0541c996c000411d2001ad10011a41e696c0004111422a10014100480d" - "0641f796c000411c420010011a419397c000411a41004100410010021a41ff97c000412941" - "004100410010021a41a898c00041281019220145044041d098c000412741a898c000412841" - "0110021a41f798c000411e41004100410010021a41bf80c000412841004100410010021a41" - "010c080b419599c000411a2001ac10011a41c37a0c070b41f494c000411d2001ac10011a41" - "8b7c0c060b41d894c000411c2001ac10011a41897c0c050b41bc94c000411c2001ac10011a" - "41887c0c040b41dd97c00041222001ac10011a41a77b0c030b000b41c797c00041162001ac" - "10011a41a57b0c010b41ad97c000411a42a47b10011a41a47b0b200041b0036a24000b0bb9" - "190100418080c0000baf196572726f725f636f64653d3d3d3d20484f53542046554e435449" - "4f4e532054455354203d3d3d54657374696e6720323620686f73742066756e6374696f6e73" - "535543434553533a20416c6c20686f73742066756e6374696f6e2074657374732070617373" - "6564212d2d2d2043617465676f727920313a204c6564676572204865616465722046756e63" - "74696f6e73202d2d2d4c65646765722073657175656e6365206e756d6265723a506172656e" - "74206c65646765722074696d653a506172656e74206c656467657220686173683a53554343" - "4553533a204c6564676572206865616465722066756e6374696f6e734552524f523a206765" - "745f706172656e745f6c65646765725f686173682077726f6e67206c656e6774683a455252" - "4f523a206765745f706172656e745f6c65646765725f74696d65206661696c65643a455252" - "4f523a206765745f6c65646765725f73716e206661696c65643a2d2d2d2043617465676f72" - "7920323a205472616e73616374696f6e20446174612046756e6374696f6e73202d2d2d5472" - "616e73616374696f6e204163636f756e743a5472616e73616374696f6e20466565206c656e" - "6774683a5472616e73616374696f6e20466565202873657269616c697a6564205852502061" - "6d6f756e74293a5472616e73616374696f6e2053657175656e63653a4e6573746564206669" - "656c64206c656e6774683a4e6573746564206669656c643a494e464f3a206765745f74785f" - "6e65737465645f6669656c64206e6f74206170706c696361626c653a5369676e6572732061" - "72726179206c656e6774683a4d656d6f73206172726179206c656e6774683a4e6573746564" - "206172726179206c656e6774683a494e464f3a206765745f74785f6e65737465645f617272" - "61795f6c656e206e6f74206170706c696361626c653a535543434553533a205472616e7361" - "6374696f6e20646174612066756e6374696f6e734552524f523a206765745f74785f666965" - "6c642853657175656e6365292077726f6e67206c656e6774683a4552524f523a206765745f" - "74785f6669656c6428466565292077726f6e67206c656e6774682028657870656374656420" - "3820627974657320666f7220585250293a4552524f523a206765745f74785f6669656c6428" - "4163636f756e74292077726f6e67206c656e6774683a2d2d2d2043617465676f727920333a" - "2043757272656e74204c6564676572204f626a6563742046756e6374696f6e73202d2d2d43" - "757272656e74206f626a6563742062616c616e6365206c656e677468202858525020616d6f" - "756e74293a43757272656e74206f626a6563742062616c616e6365202873657269616c697a" - "65642058525020616d6f756e74293a43757272656e74206f626a6563742062616c616e6365" - "206c656e67746820286e6f6e2d58525020616d6f756e74293a43757272656e74206f626a65" - "63742062616c616e63653a494e464f3a206765745f63757272656e745f6c65646765725f6f" - "626a5f6669656c642842616c616e636529206661696c656420286d61792062652065787065" - "63746564293a43757272656e74206c6564676572206f626a656374206163636f756e743a49" - "4e464f3a206765745f63757272656e745f6c65646765725f6f626a5f6669656c6428416363" - "6f756e7429206661696c65643a43757272656e74206e6573746564206669656c64206c656e" - "6774683a43757272656e74206e6573746564206669656c643a494e464f3a206765745f6375" - "7272656e745f6c65646765725f6f626a5f6e65737465645f6669656c64206e6f7420617070" - "6c696361626c653a43757272656e74206f626a656374205369676e65727320617272617920" - "6c656e6774683a43757272656e74206e6573746564206172726179206c656e6774683a494e" - "464f3a206765745f63757272656e745f6c65646765725f6f626a5f6e65737465645f617272" - "61795f6c656e206e6f74206170706c696361626c653a535543434553533a2043757272656e" - "74206c6564676572206f626a6563742066756e6374696f6e732d2d2d2043617465676f7279" - "20343a20416e79204c6564676572204f626a6563742046756e6374696f6e73202d2d2d5375" - "636365737366756c6c7920636163686564206f626a65637420696e20736c6f743a43616368" - "6564206f626a6563742062616c616e6365206c656e677468202858525020616d6f756e7429" - "3a436163686564206f626a6563742062616c616e6365202873657269616c697a6564205852" - "5020616d6f756e74293a436163686564206f626a6563742062616c616e6365206c656e6774" - "6820286e6f6e2d58525020616d6f756e74293a436163686564206f626a6563742062616c61" - "6e63653a494e464f3a206765745f6c65646765725f6f626a5f6669656c642842616c616e63" - "6529206661696c65643a436163686564206e6573746564206669656c64206c656e6774683a" - "436163686564206e6573746564206669656c643a494e464f3a206765745f6c65646765725f" - "6f626a5f6e65737465645f6669656c64206e6f74206170706c696361626c653a4361636865" - "64206f626a656374205369676e657273206172726179206c656e6774683a43616368656420" - "6e6573746564206172726179206c656e6774683a494e464f3a206765745f6c65646765725f" - "6f626a5f6e65737465645f61727261795f6c656e206e6f74206170706c696361626c653a53" - "5543434553533a20416e79206c6564676572206f626a6563742066756e6374696f6e73494e" - "464f3a2063616368655f6c65646765725f6f626a206661696c656420286578706563746564" - "20776974682074657374206669787475726573293a494e464f3a206765745f6c6564676572" - "5f6f626a5f6669656c64206661696c656420617320657870656374656420286e6f20636163" - "686564206f626a656374293a494e464f3a206765745f6c65646765725f6f626a5f6e657374" - "65645f6669656c64206661696c65642061732065787065637465643a494e464f3a20676574" - "5f6c65646765725f6f626a5f61727261795f6c656e206661696c6564206173206578706563" - "7465643a494e464f3a206765745f6c65646765725f6f626a5f6e65737465645f6172726179" - "5f6c656e206661696c65642061732065787065637465643a535543434553533a20416e7920" - "6c6564676572206f626a6563742066756e6374696f6e732028696e74657266616365207465" - "73746564294552524f523a206163636f756e745f6b65796c6574206661696c656420666f72" - "2063616368696e6720746573743a2d2d2d2043617465676f727920353a204b65796c657420" - "47656e65726174696f6e2046756e6374696f6e73202d2d2d4163636f756e74206b65796c65" - "743a546573745479706543726564656e7469616c206b65796c65743a494e464f3a20637265" - "64656e7469616c5f6b65796c6574206661696c656420286578706563746564202d20696e74" - "657266616365206973737565293a457363726f77206b65796c65743a4f7261636c65206b65" - "796c65743a535543434553533a204b65796c65742067656e65726174696f6e2066756e6374" - "696f6e734552524f523a206f7261636c655f6b65796c6574206661696c65643a4552524f52" - "3a20657363726f775f6b65796c6574206661696c65643a4552524f523a206163636f756e74" - "5f6b65796c6574206661696c65643a2d2d2d2043617465676f727920363a205574696c6974" - "792046756e6374696f6e73202d2d2d48656c6c6f2c205852504c205741534d20776f726c64" - "21496e70757420646174613a5348413531322068616c6620686173683a4e46542064617461" - "206c656e6774683a4e465420646174613a494e464f3a206765745f6e6674206661696c6564" - "20286578706563746564202d206e6f2073756368204e4654293a5465737420747261636520" - "6d6573736167657061796c6f616454726163652066756e6374696f6e206279746573207772" - "697474656e3a54657374206e756d62657220747261636554726163655f6e756d2066756e63" - "74696f6e20737563636565646564535543434553533a205574696c6974792066756e637469" - "6f6e734552524f523a2074726163655f6e756d2829206661696c65643a4552524f523a2074" - "726163652829206661696c65643a4552524f523a20636f6d707574655f7368613531325f68" - "616c66206661696c65643a2d2d2d2043617465676f727920373a2044617461205570646174" - "652046756e6374696f6e73202d2d2d55706461746564206c656467657220656e7472792064" - "6174612066726f6d205741534d20746573745375636365737366756c6c7920757064617465" - "64206c656467657220656e74727920776974683a535543434553533a204461746120757064" - "6174652066756e6374696f6e734552524f523a207570646174655f64617461206661696c65" - "643a004d0970726f64756365727302086c616e6775616765010452757374000c70726f6365" - "737365642d6279010572757374631d312e38352e3120283465623136313235302032303235" - "2d30332d31352900490f7461726765745f6665617475726573042b0f6d757461626c652d67" - "6c6f62616c732b087369676e2d6578742b0f7265666572656e63652d74797065732b0a6d75" - "6c746976616c7565"; + "20052903003700000b200020023a0000200141206a24000b460020012d0000410146044041" + "8080c000410b20013402041001000b20002001290001370000200041106a200141116a2800" + "00360000200041086a200141096a2900003700000be81901097f230041b0036b2200240041" + "8b80c000411b41004100410010021a41a680c000411941004100410010021a41e780c00041" + "2b41004100410010021a027f02400240024002400240024002401003220141004a04404192" + "81c00041172001ad10011a1004220141004c0d0141a981c00041132001ad10011a200041c8" + "016a22034200370300200041c0016a22054200370300200041b8016a220442003703002000" + "42003703b001200041b0016a22064120100522014120470d0241bc81c00041132006412041" + "0110021a41cf81c000412041004100410010021a41dc82c000412e41004100410010021a20" + "0041a0016a410036020020004198016a420037030020004200370390014181802020004190" + "016a22024114100022014114470d03418a83c00041142002411410061a2000420037037041" + "888018200041f0006a22024108100022014108470d04419e83c0004117420810011a41b583" + "c000412820024108410110021a2000410036025041848008200041d0006a22024104100022" + "014104470d0541dd83c000411520024104410110021a200041013b003c2003420037030020" + "05420037030020044200370300200042003703b00102402000413c6a410220064120100722" + "0141004e044041f283c00041142001ad10011a200041306a20062001101b418684c000410d" + "20002802302000280234410110021a0c010b419384c00041292001ac10011a0b41bc84c000" + "41154183803c1008ac10011a41d184c00041134189803c1008ac10011a02402000413c6a41" + "021009220141004e044041e484c00041142001ad10011a0c010b41f884c000412d2001ac10" + "011a0b41a585c000412341004100410010021a41de86c000413341004100410010021a2000" + "420037037041828018200041f0006a22014108100a220241004c0d06200241084604404191" + "87c000412b420810011a41bc87c000412f20014108410110021a0c080b41eb87c000412f20" + "02ad10011a200041286a200041f0006a2002101a419a88c00041172000280228200028022c" + "410110021a0c070b41bf82c000411d2001ac10011a419b7f0c070b419a82c00041252001ac" + "10011a419a7f0c060b41ef81c000412b2001ac10011a41997f0c050b41b486c000412a2001" + "ac10011a41b77e0c040b41f385c00041c1002001ac10011a41b67e0c030b41c885c000412b" + "2001ac10011a41b57e0c020b41b188c00041c5002002ac10011a0b200041a0016a41003602" + "0020004198016a4200370300200042003703900102404181802020004190016a2202411410" + "0a220141004a044041f688c000411e2002411410061a0c010b419489c00041332001ac1001" + "1a0b200041013b0050200041c8016a4200370300200041c0016a4200370300200041b8016a" + "4200370300200042003703b0010240200041d0006a4102200041b0016a22014120100b2202" + "41004e044041c789c000411c2002ad10011a200041206a20012002101b41e389c000411520" + "002802202000280224410110021a0c010b41f889c00041392002ac10011a0b41b18ac00041" + "244183803c100cac10011a0240200041d0006a4102100d220141004e044041d58ac000411c" + "2001ad10011a0c010b41f18ac000413d2001ac10011a0b41ae8bc000412841004100410010" + "021a41d68bc000412f41004100410010021a200041b0016a2202101c200041f0006a220120" + "02101d200041a8016a4200370300200041a0016a420037030020004198016a420037030020" + "00420037039001024002400240024002402001411420004190016a22024120100e22014120" + "460440200241204100100f220441004a044041858cc00041232004ad10011a200042003703" + "50200441828018200041d0006a220141081010220241004c0d022002410846044041a88cc0" + "00412a420810011a41d28cc000412e20014108410110021a0c060b41808dc000412e2002ad" + "10011a200041186a200041d0006a2002101a41ae8dc00041162000280218200028021c4101" + "10021a0c050b41e68fc000413c2004ac10011a200041c8016a4200370300200041c0016a42" + "00370300200041b8016a4200370300200042003703b001410141828018200041b0016a4120" + "101022014100480d020c030b41ba92c000412e2001ac10011a41ef7c0c050b41c48dc00041" + "2b2002ac10011a0c020b41a290c00041c1002001ac10011a0b200041013b00504101200041" + "d0006a4102200041b0016a412010112201410048044041e390c00041352001ac10011a0b41" + "014183803c101222014100480440419891c00041322001ac10011a0b4101200041d0006a41" + "0210132201410048044041ca91c00041392001ac10011a0b418392c0004137410041004100" + "10021a0c010b200041013b003c200041c8016a4200370300200041c0016a42003703002000" + "41b8016a4200370300200042003703b001024020042000413c6a4102200041b0016a220141" + "201011220241004e044041ef8dc000411b2002ad10011a200041106a20012002101b418a8e" + "c000411420002802102000280214410110021a0c010b419e8ec00041312002ac10011a0b41" + "cf8ec000412320044183803c1012ac10011a024020042000413c6a41021013220141004e04" + "4041f28ec000411b2001ad10011a0c010b418d8fc00041352001ac10011a0b41c28fc00041" + "2441004100410010021a0b41e892c000412f41004100410010021a200041b0016a2201101c" + "2000413c6a22042001101d200041e8006a4200370300200041e0006a4200370300200041d8" + "006a4200370300200042003703500240024002400240024020044114200041d0006a220241" + "20100e22014120460440419793c000410f20024120410110021a20004188016a4200370300" + "20004180016a4200370300200041f8006a4200370300200042003703700240200441142004" + "411441a693c0004109200041f0006a220141201014220241004a0440200041086a20012002" + "101b41ae93c00041122000280208200028020c410110021a0c010b41c093c000413c2002ac" + "10011a0b200041a8016a22084200370300200041a0016a2203420037030020004198016a22" + "05420037030020004200370390012000413c6a2202411441e80720004190016a2207412010" + "1522014120470d0141fc93c000410e20074120410110021a200041c8016a42003703002000" + "41c0016a4200370300200041b8016a4200370300200042003703b00120024114412a200041" + "b0016a22044120101622014120470d02418a94c000410e20044120410110021a419894c000" + "412441004100410010021a419195c000412541004100410010021a20004188016a42003703" + "0020004180016a4200370300200041f8006a42003703002000420037037041b695c0004117" + "200041f0006a22024120101722014120470d0341cd95c000410b41b695c000411741011002" + "1a41d895c000411120024120410110021a2004101c200041d0006a22062004101d20084200" + "3703002003420037030020054200370300200042003703900102404100200422036b410371" + "220220036a220520034d0d0020020440200221010340200341003a0000200341016a210320" + "0141016b22010d000b0b200241016b4107490d000340200341003a0000200341076a41003a" + "0000200341066a41003a0000200341056a41003a0000200341046a41003a0000200341036a" + "41003a0000200341026a41003a0000200341016a41003a0000200341086a22032005470d00" + "0b0b200541800220026b2201417c716a220320054b0440034020054100360200200541046a" + "22052003490d000b0b024020032001410371220120036a22024f0d00200122050440034020" + "0341003a0000200341016a2103200541016b22050d000b0b200141016b4107490d00034020" + "0341003a0000200341076a41003a0000200341066a41003a0000200341056a41003a000020" + "0341046a41003a0000200341036a41003a0000200341026a41003a0000200341016a41003a" + "0000200341086a22032002470d000b0b024020064114200741202004418002101822014100" + "4a044041e995c00041102001ad10011a20014181024f0d0641f995c0004109200420014101" + "10021a0c010b418296c000412e2001ac10011a0b41b096c000411241c296c0004107410110" + "0222014100480d0541c996c000411d2001ad10011a41e696c0004111422a10014100480440" + "41ad97c000411a42a47b10011a41a47b0c070b41f796c000411c420010011a419397c00041" + "1a41004100410010021a41ff97c000412941004100410010021a41a898c000412810192201" + "45044041d098c000412741a898c0004128410110021a41f798c000411e4100410041001002" + "1a41bf80c000412841004100410010021a41010c070b419599c000411a2001ac10011a41c3" + "7a0c060b41f494c000411d2001ac10011a418b7c0c050b41d894c000411c2001ac10011a41" + "897c0c040b41bc94c000411c2001ac10011a41887c0c030b41dd97c00041222001ac10011a" + "41a77b0c020b000b41c797c00041162001ac10011a41a57b0b200041b0036a24000b0bb919" + "0100418080c0000baf196572726f725f636f64653d3d3d3d20484f53542046554e4354494f" + "4e532054455354203d3d3d54657374696e6720323620686f73742066756e6374696f6e7353" + "5543434553533a20416c6c20686f73742066756e6374696f6e207465737473207061737365" + "64212d2d2d2043617465676f727920313a204c6564676572204865616465722046756e6374" + "696f6e73202d2d2d4c65646765722073657175656e6365206e756d6265723a506172656e74" + "206c65646765722074696d653a506172656e74206c656467657220686173683a5355434345" + "53533a204c6564676572206865616465722066756e6374696f6e734552524f523a20676574" + "5f706172656e745f6c65646765725f686173682077726f6e67206c656e6774683a4552524f" + "523a206765745f706172656e745f6c65646765725f74696d65206661696c65643a4552524f" + "523a206765745f6c65646765725f73716e206661696c65643a2d2d2d2043617465676f7279" + "20323a205472616e73616374696f6e20446174612046756e6374696f6e73202d2d2d547261" + "6e73616374696f6e204163636f756e743a5472616e73616374696f6e20466565206c656e67" + "74683a5472616e73616374696f6e20466565202873657269616c697a65642058525020616d" + "6f756e74293a5472616e73616374696f6e2053657175656e63653a4e657374656420666965" + "6c64206c656e6774683a4e6573746564206669656c643a494e464f3a206765745f74785f6e" + "65737465645f6669656c64206e6f74206170706c696361626c653a5369676e657273206172" + "726179206c656e6774683a4d656d6f73206172726179206c656e6774683a4e657374656420" + "6172726179206c656e6774683a494e464f3a206765745f74785f6e65737465645f61727261" + "795f6c656e206e6f74206170706c696361626c653a535543434553533a205472616e736163" + "74696f6e20646174612066756e6374696f6e734552524f523a206765745f74785f6669656c" + "642853657175656e6365292077726f6e67206c656e6774683a4552524f523a206765745f74" + "785f6669656c6428466565292077726f6e67206c656e677468202865787065637465642038" + "20627974657320666f7220585250293a4552524f523a206765745f74785f6669656c642841" + "63636f756e74292077726f6e67206c656e6774683a2d2d2d2043617465676f727920333a20" + "43757272656e74204c6564676572204f626a6563742046756e6374696f6e73202d2d2d4375" + "7272656e74206f626a6563742062616c616e6365206c656e677468202858525020616d6f75" + "6e74293a43757272656e74206f626a6563742062616c616e6365202873657269616c697a65" + "642058525020616d6f756e74293a43757272656e74206f626a6563742062616c616e636520" + "6c656e67746820286e6f6e2d58525020616d6f756e74293a43757272656e74206f626a6563" + "742062616c616e63653a494e464f3a206765745f63757272656e745f6c65646765725f6f62" + "6a5f6669656c642842616c616e636529206661696c656420286d6179206265206578706563" + "746564293a43757272656e74206c6564676572206f626a656374206163636f756e743a494e" + "464f3a206765745f63757272656e745f6c65646765725f6f626a5f6669656c64284163636f" + "756e7429206661696c65643a43757272656e74206e6573746564206669656c64206c656e67" + "74683a43757272656e74206e6573746564206669656c643a494e464f3a206765745f637572" + "72656e745f6c65646765725f6f626a5f6e65737465645f6669656c64206e6f74206170706c" + "696361626c653a43757272656e74206f626a656374205369676e657273206172726179206c" + "656e6774683a43757272656e74206e6573746564206172726179206c656e6774683a494e46" + "4f3a206765745f63757272656e745f6c65646765725f6f626a5f6e65737465645f61727261" + "795f6c656e206e6f74206170706c696361626c653a535543434553533a2043757272656e74" + "206c6564676572206f626a6563742066756e6374696f6e732d2d2d2043617465676f727920" + "343a20416e79204c6564676572204f626a6563742046756e6374696f6e73202d2d2d537563" + "6365737366756c6c7920636163686564206f626a65637420696e20736c6f743a4361636865" + "64206f626a6563742062616c616e6365206c656e677468202858525020616d6f756e74293a" + "436163686564206f626a6563742062616c616e6365202873657269616c697a656420585250" + "20616d6f756e74293a436163686564206f626a6563742062616c616e6365206c656e677468" + "20286e6f6e2d58525020616d6f756e74293a436163686564206f626a6563742062616c616e" + "63653a494e464f3a206765745f6c65646765725f6f626a5f6669656c642842616c616e6365" + "29206661696c65643a436163686564206e6573746564206669656c64206c656e6774683a43" + "6163686564206e6573746564206669656c643a494e464f3a206765745f6c65646765725f6f" + "626a5f6e65737465645f6669656c64206e6f74206170706c696361626c653a436163686564" + "206f626a656374205369676e657273206172726179206c656e6774683a436163686564206e" + "6573746564206172726179206c656e6774683a494e464f3a206765745f6c65646765725f6f" + "626a5f6e65737465645f61727261795f6c656e206e6f74206170706c696361626c653a5355" + "43434553533a20416e79206c6564676572206f626a6563742066756e6374696f6e73494e46" + "4f3a2063616368655f6c65646765725f6f626a206661696c65642028657870656374656420" + "776974682074657374206669787475726573293a494e464f3a206765745f6c65646765725f" + "6f626a5f6669656c64206661696c656420617320657870656374656420286e6f2063616368" + "6564206f626a656374293a494e464f3a206765745f6c65646765725f6f626a5f6e65737465" + "645f6669656c64206661696c65642061732065787065637465643a494e464f3a206765745f" + "6c65646765725f6f626a5f61727261795f6c656e206661696c656420617320657870656374" + "65643a494e464f3a206765745f6c65646765725f6f626a5f6e65737465645f61727261795f" + "6c656e206661696c65642061732065787065637465643a535543434553533a20416e79206c" + "6564676572206f626a6563742066756e6374696f6e732028696e7465726661636520746573" + "746564294552524f523a206163636f756e745f6b65796c6574206661696c656420666f7220" + "63616368696e6720746573743a2d2d2d2043617465676f727920353a204b65796c65742047" + "656e65726174696f6e2046756e6374696f6e73202d2d2d4163636f756e74206b65796c6574" + "3a546573745479706543726564656e7469616c206b65796c65743a494e464f3a2063726564" + "656e7469616c5f6b65796c6574206661696c656420286578706563746564202d20696e7465" + "7266616365206973737565293a457363726f77206b65796c65743a4f7261636c65206b6579" + "6c65743a535543434553533a204b65796c65742067656e65726174696f6e2066756e637469" + "6f6e734552524f523a206f7261636c655f6b65796c6574206661696c65643a4552524f523a" + "20657363726f775f6b65796c6574206661696c65643a4552524f523a206163636f756e745f" + "6b65796c6574206661696c65643a2d2d2d2043617465676f727920363a205574696c697479" + "2046756e6374696f6e73202d2d2d48656c6c6f2c205852504c205741534d20776f726c6421" + "496e70757420646174613a5348413531322068616c6620686173683a4e4654206461746120" + "6c656e6774683a4e465420646174613a494e464f3a206765745f6e6674206661696c656420" + "286578706563746564202d206e6f2073756368204e4654293a54657374207472616365206d" + "6573736167657061796c6f616454726163652066756e6374696f6e20627974657320777269" + "7474656e3a54657374206e756d62657220747261636554726163655f6e756d2066756e6374" + "696f6e20737563636565646564535543434553533a205574696c6974792066756e6374696f" + "6e734552524f523a2074726163655f6e756d2829206661696c65643a4552524f523a207472" + "6163652829206661696c65643a4552524f523a20636f6d707574655f7368613531325f6861" + "6c66206661696c65643a2d2d2d2043617465676f727920373a204461746120557064617465" + "2046756e6374696f6e73202d2d2d55706461746564206c656467657220656e747279206461" + "74612066726f6d205741534d20746573745375636365737366756c6c792075706461746564" + "206c656467657220656e74727920776974683a535543434553533a20446174612075706461" + "74652066756e6374696f6e734552524f523a207570646174655f64617461206661696c6564" + "3a004d0970726f64756365727302086c616e6775616765010452757374000c70726f636573" + "7365642d6279010572757374631d312e39302e30202831313539653738633420323032352d" + "30392d313429002c0f7461726765745f6665617475726573022b0f6d757461626c652d676c" + "6f62616c732b087369676e2d657874"; extern std::string const deepRecursionHex = "0061736d01000000013f0b60017f0060037f7f7f017f60027f7f017f60027f" @@ -9607,9 +9606,9 @@ extern std::string const hfPerfTest = extern std::string const allKeyletsWasmHex = "0061736d0100000001530a60057f7f7f7f7f017f60047f7f7f7f017f60067f7f7f7f7f7f01" "7f60037f7f7f017f60087f7f7f7f7f7f7f7f017f60037f7f7e017f60077f7f7f7f7f7f7f01" - "7f60057f7f7f7f7f006000017f60037f7f7f000284051808686f73745f6c69620574726163" - "65000008686f73745f6c69621063616368655f6c65646765725f6f626a000308686f73745f" - "6c69620974726163655f6e756d000508686f73745f6c6962146765745f6c65646765725f6f" + "7f60057f7f7f7f7f006000017f60037f7f7f000284051808686f73745f6c69620974726163" + "655f6e756d000508686f73745f6c6962057472616365000008686f73745f6c696210636163" + "68655f6c65646765725f6f626a000308686f73745f6c6962146765745f6c65646765725f6f" "626a5f6669656c64000108686f73745f6c69621c6765745f63757272656e745f6c65646765" "725f6f626a5f6669656c64000308686f73745f6c69620d74726163655f6163636f756e7400" "0108686f73745f6c69620e6163636f756e745f6b65796c6574000108686f73745f6c69620b" @@ -9627,227 +9626,235 @@ extern std::string const allKeyletsWasmHex = "636b65745f6b65796c6574000008686f73745f6c69620c7661756c745f6b65796c65740000" "03040307080905030100110619037f01418080c0000b7f0041958bc0000b7f0041a08bc000" "0b073e05066d656d6f727902000d6f626a6563745f65786973747300180666696e69736800" - "190a5f5f646174615f656e6403010b5f5f686561705f6261736503020a8d33038d0602057f" - "037e230041f0006b220524000240024020012d0000450440200541186a200141196a290000" - "370300200541106a200141116a290000370300200541086a200141096a2900003703002005" - "20012900013703002002200320054120410110001a2005412041001001220141004c0d0102" - "4002400240024002402004450440418b80c000410f4285801410021a200541d8006a420037" - "0300200541d0006a4200370300200541c8006a420037030020054200370340200141858014" - "200541406b22064120100322014120470d01200541286a200541cf006a2201290000220a37" - "0300200541306a200541d7006a2202290000220b370300200541386a200541df006a22032d" - "000022043a000020052005290047220c37032020052f014021072005280142210820052d00" - "4621092001200a3700002002200b370000200320043a0000200520093a0046200520083601" - "42200520073b01402005200c370047419a80c000410c20064120410110001a0c030b418b80" - "c000410f2004ac10021a200541d0006a4100360200200541c8006a42003703002005420037" - "034020012004200541406b411410032201417e47044020014114460d02200141004e0d0441" - "998ac00041172001ac10021a0c050b417e21010c040b41a680c0004115417f20012001417f" - "4e1b2201ac10021a200041013a0000200020013602040c060b200520052900473703602005" - "200541cc006a2201290000370065200520052f014022023b016e2005200529036037032020" - "05200529006537002520052800432103200520052d00423a0042200520023b014020052003" - "3600432001200529002537000020052005290320370047419a80c000410c200541406b4114" - "410110001a0b20004180023b01000c040b41b08ac0004131421410021a41e18ac000412020" - "01ad10021a417321010b41a680c00041152001ac10021a200041013a000020002001360204" - "0c020b41c280c000411620012802042201ac10021a200041013a0000200020013602040c01" - "0b41bb80c00041072001ac10021a200041013a0000200020013602040b200541f0006a2400" - "0bfc27020a7f027e23004180076b2200240041d880c000412341004100410010001a200041" - "98016a2204410036020020004190016a22034200370300200042003703880102402000027f" - "02404181802020004188016a22024114100422014114460440200041066a20002d008a013a" - "00002000200029008f013703e001200020004194016a22052900003700e501200041106a20" - "002900e501370000200020002f0188013b01042000200028008b01360007200020002903e0" - "0137000b41fb80c0004108200041046a2208411410051a2004410036020020034200370300" - "20004200370388014183802020024114100422014114470d032000411a6a20002d008a013a" - "00002000200029008f013703e001200020052900003700e501200041246a20002900e50137" - "0000200020002f0188013b01182000200028008b0136001b200020002903e00137001f4183" - "81c000410c200041186a411410051a200041a0016a22054200370300200442003703002003" - "420037030020004200370388012008411420024120100622014120460d0102402001410048" - "0440200020013602300c010b2000417f3602300b41010c020b0c020b200041c5006a200529" - "03003700002000413d6a2004290300370000200041356a2003290300370000200020002903" - "880137002d41000b3a002c20004188016a22042000412c6a418f81c0004107418180201018" - "0240024020002d00880145044041002101419681c000413541004100410010001a200041de" - "006a41c4003a0000200041d8006a4100360200200041e3006a41003a0000200041d5a6013b" - "015c200042003703502000410036005f200041a0016a2203420037030020004198016a2202" - "420037030020004190016a220542003703002000420037038801200041046a411420004118" - "6a4114200041d0006a41142004412010072204412047044002402004410048044020002004" - "3602680c010b2000417f3602680b410121010c020b200041fd006a20032903003700002000" - "41f5006a2002290300370000200041ed006a20052903003700002000200029038801370065" - "0c010b200028028c01210141878ac0004112420510021a0c010b200020013a006420004188" - "016a200041e4006a41cb81c000410941001018024020002d00880145044041d481c0004137" - "41004100410010001a200041f0016a200041286a2201280100360200200041e8016a200041" - "206a2202290100370300200041fc016a200041d8006a290300220a37020020004184026a20" - "0041e0006a2802002203360200200020002901183703e00120002000290350220b3702f401" - "200041e8066a22042003360200200041e0066a2203200a3703002000200b3703d806200041" - "f4066a2002290100370200200041fc066a2001280100360200200020002901183702ec0620" - "004188026a200041d8066a22014128101a2000418c016a200041e0016a41d000101a200041" - "0136028801200041f0066a2202420037030020044200370300200342003703002000420037" - "03d80641818bc0004114200041b4016a412820014120100822014120470440024020014100" - "480440200020013602e4010c010b2000417f3602e4010b410121010c020b200041f9016a20" - "02290300370000200041f1016a2004290300370000200041e9016a20032903003700002000" - "20002903d8063700e101410021010c010b200028028c01210141878ac0004112420510021a" - "0c010b200020013a00e001200041b4026a200041e0016a2204418b82c00041034181802010" - "18024020002d00b40245044041002101418e82c000413141004100410010001a200041f801" - "6a22034200370300200041f0016a22024200370300200041e8016a22054200370300200042" - "003703e001200041046a411441062004412010092204412047044002402004410048044020" - "0020043602c0020c010b2000417f3602c0020b410121010c020b200041d5026a2003290300" - "370000200041cd026a2002290300370000200041c5026a2005290300370000200020002903" - "e0013700bd020c010b20002802b802210141878ac0004112420610021a0c010b200020013a" - "00bc02200041e0016a2204200041bc026a41bf82c0004105418180201018024020002d00e0" - "014504404100210141c482c000413341004100410010001a200041f8016a22034200370300" - "200041f0016a22024200370300200041e8016a22054200370300200042003703e001200041" - "046a220841142008411441f782c000411220044120100a2204412047044002402004410048" - "0440200020043602e4020c010b2000417f3602e4020b410121010c020b200041f9026a2003" - "290300370000200041f1026a2002290300370000200041e9026a2005290300370000200020" - "002903e0013700e1020c010b20002802e401210141878ac0004112420610021a0c010b2000" - "20013a00e002200041e0016a2204200041e0026a418983c000410a41988020101802402000" - "2d00e00145044041002101419383c000413841004100410010001a200041f8016a22034200" - "370300200041f0016a22024200370300200041e8016a22054200370300200042003703e001" - "200041046a4114200041186a411420044120100b2204412047044002402004410048044020" - "002004360288030c010b2000417f360288030b410121010c020b2000419d036a2003290300" - "37000020004195036a20022903003700002000418d036a2005290300370000200020002903" - "e001370085030c010b20002802e401210141878ac0004112420710021a0c010b200020013a" - "008403200041e0016a220520004184036a41cb83c000410841818020101802400240024002" - "40024002400240024002400240024020002d00e00145044041d383c0004136410041004100" - "10001a230041206b22032400200341186a22064200370300200341106a2207420037030020" - "0341086a2209420037030020034200370300200041a8036a2201027f200041046a22044114" - "200041186a2208411420034120100c22024120470440024020024100480440200120023602" - "040c010b2001417f3602040b41010c010b20012003290300370001200141196a2006290300" - "370000200141116a2007290300370000200141096a200929030037000041000b3a00002003" - "41206a240020052001418984c000410e41818020101820002d00e0010d01419784c000413c" - "41004100410010001a230041206b22032400200341186a22064200370300200341106a2207" - "4200370300200341086a2209420037030020034200370300200041cc036a2201027f200441" - "1420034120100d22024120470440024020024100480440200120023602040c010b2001417f" - "3602040b41010c010b20012003290300370001200141196a2006290300370000200141116a" - "2007290300370000200141096a200929030037000041000b3a0000200341206a2400200520" - "0141d384c000410341818020101820002d00e0010d0241d684c00041314100410041001000" - "1a230041206b22032400200341186a22064200370300200341106a22074200370300200341" - "086a2209420037030020034200370300200041f0036a2201027f20044114410b2003412010" - "0e22024120470440024020024100480440200120023602040c010b2001417f3602040b4101" - "0c010b20012003290300370001200141196a2006290300370000200141116a200729030037" - "0000200141096a200929030037000041000b3a0000200341206a240020052001418785c000" - "410641818020101820002d00e0010d03418d85c000413441004100410010001a230041206b" - "22032400200341186a22064200370300200341106a22074200370300200341086a22094200" - "3703002003420037030020004194046a2201027f20044114410c20034120100f2202412047" - "0440024020024100480440200120023602040c010b2001417f3602040b41010c010b200120" - "03290300370001200141196a2006290300370000200141116a200729030037000020014109" - "6a200929030037000041000b3a0000200341206a2400200041f4016a200041146a28010036" - "0200200041ec016a2000410c6a290100370200200020002901043702e401200041808080e0" - "003602e001200041d8066a2203200141c185c000410b41848020101820002d00d8060d0441" - "cc85c000413941004100410010001a230041206b22012400200141186a2206420037030020" - "0141106a22074200370300200141086a2209420037030020014200370300200041b8046a22" - "02027f20054118200841142001412010102205412047044002402005410048044020022005" - "3602040c010b2002417f3602040b41010c010b20022001290300370001200241196a200629" - "0300370000200241116a2007290300370000200241096a200929030037000041000b3a0000" - "200141206a240020032002418586c000410741818020101820002d00d8060d05418c86c000" - "413541004100410010001a230041206b22012400200141186a22064200370300200141106a" - "22074200370300200141086a2209420037030020014200370300200041dc046a2202027f20" - "084114410620014120101122054120470440024020054100480440200220053602040c010b" - "2002417f3602040b41010c010b20022001290300370001200241196a200629030037000020" - "0241116a2007290300370000200241096a200929030037000041000b3a0000200141206a24" - "002003200241c186c000410c41828020101820002d00d8060d0641cd86c000413a41004100" - "410010001a230041206b22012400200141186a22064200370300200141106a220742003703" - "00200141086a220942003703002001420037030020004180056a2202027f20044114410d20" - "014120101222054120470440024020054100480440200220053602040c010b2002417f3602" - "040b41010c010b20022001290300370001200241196a2006290300370000200241116a2007" - "290300370000200241096a200929030037000041000b3a0000200141206a24002003200241" - "8787c000410541818020101820002d00d8060d07418c87c000413341004100410010001a23" - "0041206b22012400200141186a22064200370300200141106a22074200370300200141086a" - "2209420037030020014200370300200041a4056a2202027f2004411420084114410e200141" - "20101322054120470440024020054100480440200220053602040c010b2002417f3602040b" - "41010c010b20022001290300370001200241196a2006290300370000200241116a20072903" - "00370000200241096a200929030037000041000b3a0000200141206a24002003200241bf87" - "c000410a41818020101820002d00d8060d0841c987c000413841004100410010001a230041" - "206b22012400200141186a22084200370300200141106a22064200370300200141086a2207" - "420037030020014200370300200041c8056a2202027f20044114410f200141201014220541" - "20470440024020054100480440200220053602040c010b2002417f3602040b41010c010b20" - "022001290300370001200241196a2008290300370000200241116a20062903003700002002" - "41096a200729030037000041000b3a0000200141206a240020032002418188c00041124182" - "8020101820002d00d8060d09419388c00041c00041004100410010001a230041206b220124" - "00200141186a22084200370300200141106a22064200370300200141086a22074200370300" - "20014200370300200041ec056a2202027f2004411420014120101522054120470440024020" - "054100480440200220053602040c010b2002417f3602040b41010c010b2002200129030037" - "0001200241196a2008290300370000200241116a2006290300370000200241096a20072903" - "0037000041000b3a0000200141206a24002003200241d388c000410a4100101820002d00d8" - "060d0a41dd88c000413841004100410010001a230041206b22012400200141186a22084200" - "370300200141106a22064200370300200141086a2207420037030020014200370300200041" - "90066a2202027f200441144112200141201016220541204704400240200541004804402002" - "20053602040c010b2002417f3602040b41010c010b20022001290300370001200241196a20" - "08290300370000200241116a2006290300370000200241096a200729030037000041000b3a" - "0000200141206a240020032002419589c000410641818020101820002d00d8060d0b419b89" - "c000413441004100410010001a230041206b22012400200141186a22054200370300200141" - "106a22084200370300200141086a2206420037030020014200370300200041b4066a220202" - "7f20044114411320014120101722044120470440024020044100480440200220043602040c" - "010b2002417f3602040b41010c010b20022001290300370001200241196a20052903003700" - "00200241116a2008290300370000200241096a200629030037000041000b3a000020014120" - "6a24002003200241cf89c000410541818020101820002d00d80645044041d489c000413341" - "004100410010001a410121010c0d0b20002802dc06210141878ac0004112421310021a0c0c" - "0b20002802e401210141878ac0004112420810021a0c0b0b20002802e401210141878ac000" - "4112420910021a0c0a0b20002802e401210141878ac0004112420a10021a0c090b20002802" - "e401210141878ac0004112420b10021a0c080b20002802dc06210141878ac0004112420c10" - "021a0c070b20002802dc06210141878ac0004112420d10021a0c060b20002802dc06210141" - "878ac0004112420d10021a0c050b20002802dc06210141878ac0004112420d10021a0c040b" - "20002802dc06210141878ac0004112420e10021a0c030b20002802dc06210141878ac00041" - "12420f10021a0c020b20002802dc06210141878ac0004112421010021a0c010b20002802dc" - "06210141878ac0004112421210021a0b20004180076a240020010f0b418080c000410b417f" - "20012001417f4e1bac1002000bfd0401067f200241104f044002402000410020006b410371" - "22056a220420004d0d002001210320050440200521060340200020032d00003a0000200341" - "016a2103200041016a2100200641016b22060d000b0b200541016b4107490d000340200020" - "032d00003a0000200041016a200341016a2d00003a0000200041026a200341026a2d00003a" - "0000200041036a200341036a2d00003a0000200041046a200341046a2d00003a0000200041" - "056a200341056a2d00003a0000200041066a200341066a2d00003a0000200041076a200341" - "076a2d00003a0000200341086a2103200041086a22002004470d000b0b2004200220056b22" - "07417c7122086a21000240200120056a2206410371450440200020044d0d01200621010340" - "20042001280200360200200141046a2101200441046a22042000490d000b0c010b20002004" - "4d0d002006410374220541187121032006417c71220241046a2101410020056b4118712105" - "200228020021020340200420022003762001280200220220057472360200200141046a2101" - "200441046a22042000490d000b0b20074103712102200620086a21010b0240200020002002" - "6a22064f0d002002410771220304400340200020012d00003a0000200141016a2101200041" - "016a2100200341016b22030d000b0b200241016b4107490d000340200020012d00003a0000" - "200041016a200141016a2d00003a0000200041026a200141026a2d00003a0000200041036a" - "200141036a2d00003a0000200041046a200141046a2d00003a0000200041056a200141056a" - "2d00003a0000200041066a200141066a2d00003a0000200041076a200141076a2d00003a00" - "00200141086a2101200041086a22002006470d000b0b0b0b8b0b0100418080c0000b810b65" - "72726f725f636f64653d47657474696e67206669656c643a204669656c6420646174613a20" - "4572726f722067657474696e67206669656c643a204572726f723a204572726f7220676574" - "74696e67206b65796c65743a202424242424205354415254494e47205741534d2045584543" - "5554494f4e2024242424244163636f756e743a44657374696e6174696f6e3a4163636f756e" - "744163636f756e74206f626a656374206578697374732c2070726f63656564696e67207769" - "746820657363726f772066696e6973682e54727573746c696e6554727573746c696e65206f" + "190a5f5f646174615f656e6403010b5f5f686561705f6261736503020ae53503900602047f" + "037e230041f0006b22052400024020012d0000410146044041c280c0004116200128020422" + "01ac10001a200041013a0000200020013602040c010b200541186a200141196a2900003703" + "00200541106a200141116a290000370300200541086a200141096a29000037030020052001" + "2900013703002002200320054120410110011a02402005412041001002220141004a044002" + "400240024002402004450440418b80c000410f4285801410001a200541d8006a4200370300" + "200541d0006a4200370300200541c8006a4200370300200542003703402001418580142005" + "41406b4120100322014120460d0141a680c0004115417f20012001417f4e1b2201ac10001a" + "200041013a0000200020013602040c070b418b80c000410f2004ac10001a200541d0006a41" + "00360200200541c8006a42003703002005420037034020012004200541406b411410032201" + "417e47044020014114460d04200141004e0d0241ad8ac00041172001ac10001a0c030b417e" + "21010c020b200541286a200541cf006a22012900002209370300200541306a200541d7006a" + "2202290000220a370300200541386a200541df006a22032d000022043a0000200520052900" + "47220b37032020052f014021062005280142210720052d0046210820012009370000200220" + "0a370000200320043a0000200520083a004620052007360142200520063b01402005200b37" + "0047419a80c000410c200541406b4120410110011a0c040b41c48ac0004131421410001a41" + "f58ac00041202001ad10001a417321010b41a680c00041152001ac10001a200041013a0000" + "200020013602040c030b200520052900473703602005200541cc006a220129000037006520" + "0520052f014022023b016e2005200529036037032020052005290065370025200528004321" + "03200520052d00423a0042200520023b014020052003360043200120052900253700002005" + "2005290320370047419a80c000410c200541406b4114410110011a0c010b41bb80c0004107" + "2001ac10001a200041013a0000200020013602040c010b20004180023b01000b200541f000" + "6a24000bd92802077f027e23004180076b2200240041d880c000412341004100410010011a" + "20004198016a2201410036020020004190016a220242003703002000420037038801024020" + "00027f02404181802020004188016a22044114100422034114460440200041066a20002d00" + "8a013a00002000200029008f013703e001200020004194016a22052900003700e501200041" + "106a20002900e501370000200020002f0188013b01042000200028008b0136000720002000" + "2903e00137000b41fb80c0004108200041046a2206411410051a2001410036020020024200" + "37030020004200370388014183802020044114100422034114470d032000411a6a20002d00" + "8a013a00002000200029008f013703e001200020052900003700e501200041246a20002900" + "e501370000200020002f0188013b01182000200028008b0136001b200020002903e0013700" + "1f418381c000410c200041186a411410051a200041a0016a22054200370300200142003703" + "002002420037030020004200370388012006411420044120100622034120460d0102402003" + "4100480440200020033602300c010b2000417f3602300b41010c020b0c020b200041c5006a" + "20052903003700002000413d6a2001290300370000200041356a2002290300370000200020" + "002903880137002d41000b3a002c20004188016a2000412c6a418f81c00041074181802010" + "18024020002d0088014101460440200028028c01210341878ac0004112420510001a0c010b" + "41002103419681c000413541004100410010011a200041de006a41c4003a0000200041d800" + "6a4100360200200041e3006a41003a0000200041d5a6013b015c2000420037035020004100" + "36005f200041a0016a2202420037030020004198016a2204420037030020004190016a2205" + "420037030020004200370388010240200041046a4114200041186a4114200041d0006a4114" + "20004188016a4120100722014120470440024020014100480440200020013602680c010b20" + "00417f3602680b410121030c010b200041fd006a2002290300370000200041f5006a200429" + "0300370000200041ed006a200529030037000020002000290388013700650b200020033a00" + "6420004188016a200041e4006a41cb81c00041094100101820002d00880141014604402000" + "28028c01210341878ac0004112420510001a0c010b41d481c000413741004100410010011a" + "200041f0016a200041286a2203280100360200200041e8016a200041206a22042901003703" + "00200041fc016a200041d8006a290300220737020020004184026a200041e0006a28020022" + "02360200200020002901183703e0012000200029035022083702f401200041e8066a220120" + "02360200200041e0066a22022007370300200020083703d806200041f4066a200429010037" + "0200200041fc066a2003280100360200200020002901183702ec0620004188026a200041d8" + "066a22034128101a2000418c016a200041e0016a41d000101a2000410136028801200041f0" + "066a220442003703002001420037030020024200370300200042003703d8062000027f4199" + "8ac0004114200041b4016a4128200341201008220341204704400240200341004804402000" + "20033602e4010c010b2000417f3602e4010b41010c010b200041f9016a2004290300370000" + "200041f1016a2001290300370000200041e9016a2002290300370000200020002903d80637" + "00e10141000b3a00e001200041b4026a200041e0016a418b82c00041034181802010182000" + "2d00b402410146044020002802b802210341878ac0004112420610001a0c010b4100210341" + "8e82c000413141004100410010011a200041f8016a22024200370300200041f0016a220442" + "00370300200041e8016a22054200370300200042003703e0010240200041046a4114410620" + "0041e0016a4120100922014120470440024020014100480440200020013602c0020c010b20" + "00417f3602c0020b410121030c010b200041d5026a2002290300370000200041cd026a2004" + "290300370000200041c5026a2005290300370000200020002903e0013700bd020b20002003" + "3a00bc02200041e0016a200041bc026a41bf82c000410541818020101820002d00e0014101" + "46044020002802e401210341878ac0004112420610001a0c010b4100210341c482c0004133" + "41004100410010011a200041f8016a22024200370300200041f0016a220442003703002000" + "41e8016a22054200370300200042003703e0010240200041046a220141142001411441f782" + "c0004112200041e0016a4120100a22014120470440024020014100480440200020013602e4" + "020c010b2000417f3602e4020b410121030c010b200041f9026a2002290300370000200041" + "f1026a2004290300370000200041e9026a2005290300370000200020002903e0013700e102" + "0b200020033a00e002200041e0016a200041e0026a418983c000410a41988020101820002d" + "00e001410146044020002802e401210341878ac0004112420710001a0c010b410021034193" + "83c000413841004100410010011a200041f8016a22024200370300200041f0016a22044200" + "370300200041e8016a22054200370300200042003703e0010240200041046a411420004118" + "6a4114200041e0016a4120100b220141204704400240200141004804402000200136028803" + "0c010b2000417f360288030b410121030c010b2000419d036a200229030037000020004195" + "036a20042903003700002000418d036a2005290300370000200020002903e001370085030b" + "200020033a008403200041e0016a20004184036a41cb83c000410841818020101820002d00" + "e001410146044020002802e401210341878ac0004112420810001a0c010b41d383c0004136" + "41004100410010011a230041206b22012400200141186a22044200370300200141106a2205" + "4200370300200141086a2206420037030020014200370300200041a8036a2202027f200041" + "046a4114200041186a411420014120100c2203412047044002402003410048044020022003" + "3602040c010b2002417f3602040b41010c010b20022001290300370001200241196a200429" + "0300370000200241116a2005290300370000200241096a200629030037000041000b3a0000" + "200141206a2400200041e0016a2002418984c000410e41818020101820002d00e001410146" + "044020002802e401210341878ac0004112420910001a0c010b419784c000413c4100410041" + "0010011a230041206b22012400200141186a22044200370300200141106a22054200370300" + "200141086a2206420037030020014200370300200041cc036a2202027f200041046a411420" + "014120100d22034120470440024020034100480440200220033602040c010b2002417f3602" + "040b41010c010b20022001290300370001200241196a2004290300370000200241116a2005" + "290300370000200241096a200629030037000041000b3a0000200141206a2400200041e001" + "6a200241d384c000410341818020101820002d00e001410146044020002802e40121034187" + "8ac0004112420a10001a0c010b41d684c000413141004100410010011a230041206b220124" + "00200141186a22044200370300200141106a22054200370300200141086a22064200370300" + "20014200370300200041f0036a2202027f200041046a4114410b20014120100e2203412047" + "0440024020034100480440200220033602040c010b2002417f3602040b41010c010b200220" + "01290300370001200241196a2004290300370000200241116a200529030037000020024109" + "6a200629030037000041000b3a0000200141206a2400200041e0016a2002418785c0004106" + "41818020101820002d00e001410146044020002802e401210341878ac0004112420b10001a" + "0c010b418d85c000413441004100410010011a230041206b22012400200141186a22044200" + "370300200141106a22054200370300200141086a2206420037030020014200370300200041" + "94046a2202027f200041046a4114410c20014120100f220341204704400240200341004804" + "40200220033602040c010b2002417f3602040b41010c010b20022001290300370001200241" + "196a2004290300370000200241116a2005290300370000200241096a200629030037000041" + "000b3a0000200141206a2400200041f4016a200041146a280100360200200041ec016a2000" + "410c6a290100370200200020002901043702e401200041808080e0003602e001200041d806" + "6a200241c185c000410b41848020101820002d00d806410146044020002802dc0621034187" + "8ac0004112420c10001a0c010b41cc85c000413941004100410010011a230041206b220124" + "00200141186a22044200370300200141106a22054200370300200141086a22064200370300" + "20014200370300200041b8046a2202027f200041e0016a4118200041186a41142001412010" + "1022034120470440024020034100480440200220033602040c010b2002417f3602040b4101" + "0c010b20022001290300370001200241196a2004290300370000200241116a200529030037" + "0000200241096a200629030037000041000b3a0000200141206a2400200041d8066a200241" + "8586c000410741818020101820002d00d806410146044020002802dc06210341878ac00041" + "12420d10001a0c010b418c86c000413541004100410010011a230041206b22012400200141" + "186a22044200370300200141106a22054200370300200141086a2206420037030020014200" + "370300200041dc046a2202027f200041186a41144106200141201011220341204704400240" + "20034100480440200220033602040c010b2002417f3602040b41010c010b20022001290300" + "370001200241196a2004290300370000200241116a2005290300370000200241096a200629" + "030037000041000b3a0000200141206a2400200041d8066a200241c186c000410c41828020" + "101820002d00d806410146044020002802dc06210341878ac0004112420d10001a0c010b41" + "cd86c000413a41004100410010011a230041206b22012400200141186a2204420037030020" + "0141106a22054200370300200141086a220642003703002001420037030020004180056a22" + "02027f200041046a4114410d20014120101222034120470440024020034100480440200220" + "033602040c010b2002417f3602040b41010c010b20022001290300370001200241196a2004" + "290300370000200241116a2005290300370000200241096a200629030037000041000b3a00" + "00200141206a2400200041d8066a2002418787c000410541818020101820002d00d8064101" + "46044020002802dc06210341878ac0004112420d10001a0c010b418c87c000413341004100" + "410010011a230041206b22012400200141186a22044200370300200141106a220542003703" + "00200141086a2206420037030020014200370300200041a4056a2202027f200041046a4114" + "200041186a4114410e20014120101322034120470440024020034100480440200220033602" + "040c010b2002417f3602040b41010c010b20022001290300370001200241196a2004290300" + "370000200241116a2005290300370000200241096a200629030037000041000b3a00002001" + "41206a2400200041d8066a200241bf87c000410a41818020101820002d00d8064101460440" + "20002802dc06210341878ac0004112420e10001a0c010b41c987c000413841004100410010" + "011a230041206b22012400200141186a22044200370300200141106a220542003703002001" + "41086a2206420037030020014200370300200041c8056a2202027f200041046a4114410f20" + "014120101422034120470440024020034100480440200220033602040c010b2002417f3602" + "040b41010c010b20022001290300370001200241196a2004290300370000200241116a2005" + "290300370000200241096a200629030037000041000b3a0000200141206a2400200041d806" + "6a2002418188c000411241828020101820002d00d806410146044020002802dc0621034187" + "8ac0004112420f10001a0c010b419388c00041c00041004100410010011a230041206b2201" + "2400200141186a22044200370300200141106a22054200370300200141086a220642003703" + "0020014200370300200041ec056a2202027f200041046a4114200141201015220341204704" + "40024020034100480440200220033602040c010b2002417f3602040b41010c010b20022001" + "290300370001200241196a2004290300370000200241116a2005290300370000200241096a" + "200629030037000041000b3a0000200141206a2400200041d8066a200241d388c000410a41" + "00101820002d00d806410146044020002802dc06210341878ac0004112421010001a0c010b" + "41dd88c000413841004100410010011a230041206b22012400200141186a22044200370300" + "200141106a22054200370300200141086a220642003703002001420037030020004190066a" + "2202027f200041046a41144112200141201016220341204704400240200341004804402002" + "20033602040c010b2002417f3602040b41010c010b20022001290300370001200241196a20" + "04290300370000200241116a2005290300370000200241096a200629030037000041000b3a" + "0000200141206a2400200041d8066a2002419589c000410641818020101820002d00d80641" + "0146044020002802dc06210341878ac0004112421210001a0c010b419b89c0004134410041" + "00410010011a230041206b22012400200141186a22044200370300200141106a2205420037" + "0300200141086a2206420037030020014200370300200041b4066a2202027f200041046a41" + "14411320014120101722034120470440024020034100480440200220033602040c010b2002" + "417f3602040b41010c010b20022001290300370001200241196a2004290300370000200241" + "116a2005290300370000200241096a200629030037000041000b3a0000200141206a240020" + "0041d8066a200241cf89c00041054181802010184101210320002d00d80641014604402000" + "2802dc06210341878ac0004112421310001a0c010b41d489c000413341004100410010011a" + "0b20004180076a240020030f0b418080c000410b417f20032003417f4e1bac1000000bf506" + "010b7f230041106b2106200241104f0440024020002000410020006b41037122056a22044f" + "0d002001210320050440200521070340200020032d00003a0000200341016a210320004101" + "6a2100200741016b22070d000b0b200541016b4107490d000340200020032d00003a000020" + "0041016a200341016a2d00003a0000200041026a200341026a2d00003a0000200041036a20" + "0341036a2d00003a0000200041046a200341046a2d00003a0000200041056a200341056a2d" + "00003a0000200041066a200341066a2d00003a0000200041076a200341076a2d00003a0000" + "200341086a2103200041086a22002004470d000b0b2004200220056b220b417c71220c6a21" + "000240200120056a22034103712201450440200020044d0d01200321010340200420012802" + "00360200200141046a2101200441046a22042000490d000b0c010b41002102200641003602" + "0c2006410c6a2001722105410420016b22074101710440200520032d00003a000041012102" + "0b20074102710440200220056a200220036a2f01003b01000b200320016b21022001410374" + "2107200628020c210902402000200441046a4d0440200421050c010b410020076b41187121" + "08034020042009200776200241046a2202280200220920087472360200200441086a210a20" + "0441046a220521042000200a4b0d000b0b41002104200641003a0008200641003a0006027f" + "200141014604404100210141002108200641086a0c010b200241056a2d0000200620024104" + "6a2d000022013a000841087421084102210d200641066a0b210a20052003410171047f200a" + "200241046a200d6a2d00003a000020062d0006411074210420062d00080520010b41ff0171" + "200420087272410020076b411871742009200776723602000b200b41037121022003200c6a" + "21010b02402000200020026a22044f0d002002410771220304400340200020012d00003a00" + "00200141016a2101200041016a2100200341016b22030d000b0b200241016b4107490d0003" + "40200020012d00003a0000200041016a200141016a2d00003a0000200041026a200141026a" + "2d00003a0000200041036a200141036a2d00003a0000200041046a200141046a2d00003a00" + "00200041056a200141056a2d00003a0000200041066a200141066a2d00003a000020004107" + "6a200141076a2d00003a0000200141086a2101200041086a22002004470d000b0b0b0b930b" + "0200418080c0000b990a6572726f725f636f64653d47657474696e67206669656c643a2046" + "69656c6420646174613a204572726f722067657474696e67206669656c643a204572726f72" + "3a204572726f722067657474696e67206b65796c65743a202424242424205354415254494e" + "47205741534d20455845435554494f4e2024242424244163636f756e743a44657374696e61" + "74696f6e3a4163636f756e744163636f756e74206f626a656374206578697374732c207072" + "6f63656564696e67207769746820657363726f772066696e6973682e54727573746c696e65" + "54727573746c696e65206f626a656374206578697374732c2070726f63656564696e672077" + "69746820657363726f772066696e6973682e414d4d414d4d206f626a656374206578697374" + "732c2070726f63656564696e67207769746820657363726f772066696e6973682e43686563" + "6b436865636b206f626a656374206578697374732c2070726f63656564696e672077697468" + "20657363726f772066696e6973682e7465726d73616e64636f6e646974696f6e7343726564" + "656e7469616c43726564656e7469616c206f626a656374206578697374732c2070726f6365" + "6564696e67207769746820657363726f772066696e6973682e44656c656761746544656c65" + "67617465206f626a656374206578697374732c2070726f63656564696e6720776974682065" + "7363726f772066696e6973682e4465706f736974507265617574684465706f736974507265" + "61757468206f626a656374206578697374732c2070726f63656564696e6720776974682065" + "7363726f772066696e6973682e444944444944206f626a656374206578697374732c207072" + "6f63656564696e67207769746820657363726f772066696e6973682e457363726f77457363" + "726f77206f626a656374206578697374732c2070726f63656564696e672077697468206573" + "63726f772066696e6973682e4d505449737375616e63654d505449737375616e6365206f62" + "6a656374206578697374732c2070726f63656564696e67207769746820657363726f772066" + "696e6973682e4d50546f6b656e4d50546f6b656e206f626a656374206578697374732c2070" + "726f63656564696e67207769746820657363726f772066696e6973682e4e46546f6b656e4f" + "666665724e46546f6b656e4f66666572206f626a656374206578697374732c2070726f6365" + "6564696e67207769746820657363726f772066696e6973682e4f666665724f66666572206f" "626a656374206578697374732c2070726f63656564696e67207769746820657363726f7720" - "66696e6973682e414d4d414d4d206f626a656374206578697374732c2070726f6365656469" - "6e67207769746820657363726f772066696e6973682e436865636b436865636b206f626a65" - "6374206578697374732c2070726f63656564696e67207769746820657363726f772066696e" - "6973682e7465726d73616e64636f6e646974696f6e7343726564656e7469616c4372656465" - "6e7469616c206f626a656374206578697374732c2070726f63656564696e67207769746820" - "657363726f772066696e6973682e44656c656761746544656c6567617465206f626a656374" + "66696e6973682e5061794368616e6e656c5061794368616e6e656c206f626a656374206578" + "697374732c2070726f63656564696e67207769746820657363726f772066696e6973682e50" + "65726d697373696f6e6564446f6d61696e5065726d697373696f6e6564446f6d61696e206f" + "626a656374206578697374732c2070726f63656564696e67207769746820657363726f7720" + "66696e6973682e5369676e65724c6973745369676e65724c697374206f626a656374206578" + "697374732c2070726f63656564696e67207769746820657363726f772066696e6973682e54" + "69636b65745469636b6574206f626a656374206578697374732c2070726f63656564696e67" + "207769746820657363726f772066696e6973682e5661756c745661756c74206f626a656374" "206578697374732c2070726f63656564696e67207769746820657363726f772066696e6973" - "682e4465706f736974507265617574684465706f73697450726561757468206f626a656374" - "206578697374732c2070726f63656564696e67207769746820657363726f772066696e6973" - "682e444944444944206f626a656374206578697374732c2070726f63656564696e67207769" - "746820657363726f772066696e6973682e457363726f77457363726f77206f626a65637420" - "6578697374732c2070726f63656564696e67207769746820657363726f772066696e697368" - "2e4d505449737375616e63654d505449737375616e6365206f626a65637420657869737473" - "2c2070726f63656564696e67207769746820657363726f772066696e6973682e4d50546f6b" - "656e4d50546f6b656e206f626a656374206578697374732c2070726f63656564696e672077" - "69746820657363726f772066696e6973682e4e46546f6b656e4f666665724e46546f6b656e" - "4f66666572206f626a656374206578697374732c2070726f63656564696e67207769746820" - "657363726f772066696e6973682e4f666665724f66666572206f626a656374206578697374" - "732c2070726f63656564696e67207769746820657363726f772066696e6973682e50617943" - "68616e6e656c5061794368616e6e656c206f626a656374206578697374732c2070726f6365" - "6564696e67207769746820657363726f772066696e6973682e5065726d697373696f6e6564" - "446f6d61696e5065726d697373696f6e6564446f6d61696e206f626a656374206578697374" - "732c2070726f63656564696e67207769746820657363726f772066696e6973682e5369676e" - "65724c6973745369676e65724c697374206f626a656374206578697374732c2070726f6365" - "6564696e67207769746820657363726f772066696e6973682e5469636b65745469636b6574" - "206f626a656374206578697374732c2070726f63656564696e67207769746820657363726f" - "772066696e6973682e5661756c745661756c74206f626a656374206578697374732c207072" - "6f63656564696e67207769746820657363726f772066696e6973682e43757272656e742073" - "65712076616c75653a456e636f756e7465726564206572726f725f636f64653a4279746520" - "61727261792077617320657870656374656420746f20686176652074686973206d616e7920" - "62797465733a2042797465206172726179206861642074686973206d616e79206279746573" - "3a20004d0970726f64756365727302086c616e6775616765010452757374000c70726f6365" - "737365642d6279010572757374631d312e38352e3120283465623136313235302032303235" - "2d30332d31352900490f7461726765745f6665617475726573042b0f6d757461626c652d67" - "6c6f62616c732b087369676e2d6578742b0f7265666572656e63652d74797065732b0a6d75" - "6c746976616c7565"; + "682e43757272656e74207365712076616c75653a0041ad8ac0000b68456e636f756e746572" + "6564206572726f725f636f64653a4279746520617272617920776173206578706563746564" + "20746f20686176652074686973206d616e792062797465733a204279746520617272617920" + "6861642074686973206d616e792062797465733a20004d0970726f64756365727302086c61" + "6e6775616765010452757374000c70726f6365737365642d6279010572757374631d312e39" + "302e30202831313539653738633420323032352d30392d313429002c0f7461726765745f66" + "65617475726573022b0f6d757461626c652d676c6f62616c732b087369676e2d657874"; extern std::string const codecovTestsWasmHex = "0061736d0100000001570b60047f7f7f7f017f60057f7f7f7f7f017f60027f7f017f60067f" @@ -9924,8 +9931,8 @@ extern std::string const codecovTestsWasmHex = "3b01382000200028005b36003b2000200029005f37003f200041386a41204100100b410141" "8881c0004110103e2003410036020020024200370300200042003703584181802020014114" "100c411441e48cc000411c103e200341003602002002420037030020004200370358410141" - "81802020014114100d411441808dc0004114103e02402001410020016b41037122036a2202" - "20014d0d0020030440200321050340200141003a0000200141016a2101200541016b22050d" + "81802020014114100d411441808dc0004114103e024020012001410020016b41037122036a" + "22024f0d0020030440200321050340200141003a0000200141016a2101200541016b22050d" "000b0b200341016b4107490d000340200141003a0000200141076a41003a0000200141066a" "41003a0000200141056a41003a0000200141046a41003a0000200141036a41003a00002001" "41026a41003a0000200141016a41003a0000200141086a22012002470d000b0b200241c400" @@ -10157,158 +10164,117 @@ extern std::string const codecovTestsWasmHex = "6f6e675f73697a655f6163636f756e7469646765745f6e66745f77726f6e675f73697a655f" "6163636f756e7469646d70746f6b656e5f6b65796c65745f6d707469645f77726f6e675f6c" "656e677468004d0970726f64756365727302086c616e6775616765010452757374000c7072" - "6f6365737365642d6279010572757374631d312e38352e3120283465623136313235302032" - "3032352d30332d31352900490f7461726765745f6665617475726573042b0f6d757461626c" - "652d676c6f62616c732b087369676e2d6578742b0f7265666572656e63652d74797065732b" - "0a6d756c746976616c7565"; + "6f6365737365642d6279010572757374631d312e39302e3020283131353965373863342032" + "3032352d30392d313429002c0f7461726765745f6665617475726573022b0f6d757461626c" + "652d676c6f62616c732b087369676e2d657874"; extern std::string const floatTestsWasmHex = - "0061736d0100000001430860057f7f7f7f7f017f60047e7f7f7f017f60047f7f7f7f017f60" - "057f7e7f7f7f017f60077f7f7f7f7f7f7f017f60067f7f7f7f7f7f017f60037f7f7e017f60" - "00017f02c9020e08686f73745f6c6962057472616365000008686f73745f6c69620e666c6f" - "61745f66726f6d5f696e74000108686f73745f6c69620f666c6f61745f66726f6d5f75696e" - "74000008686f73745f6c69621274726163655f6f70617175655f666c6f6174000208686f73" - "745f6c696209666c6f61745f736574000308686f73745f6c69620d666c6f61745f636f6d70" - "617265000208686f73745f6c696209666c6f61745f616464000408686f73745f6c69620e66" - "6c6f61745f7375627472616374000408686f73745f6c69620e666c6f61745f6d756c746970" - "6c79000408686f73745f6c69620c666c6f61745f646976696465000408686f73745f6c6962" - "09666c6f61745f706f77000508686f73745f6c69620974726163655f6e756d000608686f73" - "745f6c69620a666c6f61745f726f6f74000508686f73745f6c696209666c6f61745f6c6f67" - "00000302010705030100110619037f01418080c0000b7f0041b48ac0000b7f0041c08ac000" + "0061736d0100000001430860077f7f7f7f7f7f7f017f60057f7f7f7f7f017f60047f7f7f7f" + "017f60067f7f7f7f7f7f017f60047e7f7f7f017f60057f7e7f7f7f017f60037f7f7e017f60" + "00017f02c9020e08686f73745f6c6962057472616365000108686f73745f6c69620e666c6f" + "61745f66726f6d5f696e74000408686f73745f6c69621274726163655f6f70617175655f66" + "6c6f6174000208686f73745f6c69620f666c6f61745f66726f6d5f75696e74000108686f73" + "745f6c696209666c6f61745f736574000508686f73745f6c69620d666c6f61745f636f6d70" + "617265000208686f73745f6c696209666c6f61745f616464000008686f73745f6c69620e66" + "6c6f61745f7375627472616374000008686f73745f6c69620e666c6f61745f6d756c746970" + "6c79000008686f73745f6c69620c666c6f61745f646976696465000008686f73745f6c6962" + "09666c6f61745f706f77000308686f73745f6c69620974726163655f6e756d000608686f73" + "745f6c69620a666c6f61745f726f6f74000308686f73745f6c696209666c6f61745f6c6f67" + "00010302010705030100110619037f01418080c0000b7f0041d28ac0000b7f0041e08ac000" "0b072e04066d656d6f727902000666696e697368000e0a5f5f646174615f656e6403010b5f" - "5f686561705f6261736503020acf1301cc1301027f23808080800041206b22002480808080" - "00418080c08000411d4100410041001080808080001a2000420037031002400240428ce000" - "200041106a410841001081808080004108470d00419d80c080004117200041106a41084101" - "1080808080001a0c010b41b480c08000411e4100410041001080808080001a0b2000428ce0" - "0037031802400240200041186a4108200041106a410841001082808080004108470d0041d2" - "80c080004117200041106a41081083808080001a0c010b41e980c08000411e410041004100" - "1080808080001a0b02400240410242fb00200041106a410841001084808080004108470d00" - "418781c080004121200041106a41081083808080001a0c010b41a881c08000412641004100" - "41001080808080001a0b41ce81c08000411541e381c0800041081083808080001a41f381c0" - "8000411641eb81c0800041081083808080001a418982c08000411b41004100410010808080" - "80001a20004200370318024002404201200041186a410841001081808080004108470d0041" - "a482c08000410f200041186a41081083808080001a0c010b41b382c0800041164100410041" - "001080808080001a0b02400240200041186a410841e381c0800041081085808080000d0041" - "c982c08000411b4100410041001080808080001a0c010b41e482c08000411b410041004100" - "1080808080001a0b02400240200041186a410841eb81c0800041081085808080004101470d" - "0041ff82c0800041234100410041001080808080001a0c010b41a283c08000412441004100" - "41001080808080001a0b0240024041eb81c080004108200041186a41081085808080004102" - "470d0041c683c0800041234100410041001080808080001a0c010b41e983c0800041244100" - "410041001080808080001a0b418d84c0800041204100410041001080808080001a200042d4" - "87b6f4c7d4b1c000370310410921010340200041106a410841e381c080004108200041106a" - "410841001086808080001a2001417f6a22010d000b20004200370318420a200041186a4108" - "41001081808080001a02400240200041186a4108200041106a41081085808080000d0041ad" - "84c0800041144100410041001080808080001a0c010b41c184c08000411341004100410010" - "80808080001a0b410b21010340200041106a410841e381c080004108200041106a41084100" - "1087808080001a2001417f6a22010d000b02400240200041106a410841eb81c08000410810" - "85808080000d0041d484c0800041194100410041001080808080001a0c010b41ed84c08000" - "41184100410041001080808080001a0b418585c0800041234100410041001080808080001a" - "20004200370300420a2000410841001081808080001a200042d487b6f4c7d4b1c000370308" - "410621010340200041086a410820004108200041086a410841001088808080001a2001417f" - "6a22010d000b2000420037031042c0843d200041106a410841001081808080001a02400240" - "200041106a4108200041086a41081085808080000d0041a885c08000411941004100410010" - "80808080001a0c010b41c185c0800041184100410041001080808080001a0b410721010340" - "200041086a410820004108200041086a410841001089808080001a2001417f6a22010d000b" - "20004200370318417f4201200041186a410841001084808080001a02400240200041086a41" - "08200041186a41081085808080000d0041d985c0800041174100410041001080808080001a" - "0c010b41f085c0800041164100410041001080808080001a0b418686c08000411741004100" - "41001080808080001a2000420037030841e381c0800041084103200041086a41084100108a" - "808080001a419d86c080004112200041086a41081083808080001a41eb81c0800041084106" - "200041086a41084100108a808080001a41af86c080004118200041086a4108108380808000" - "1a200042003703104209200041106a410841001081808080001a200041106a410841022000" - "41086a41084100108a808080001a41c786c080004114200041086a41081083808080001a20" - "0041106a41084100200041086a41084100108a808080001a41db86c080004117200041086a" - "41081083808080001a200042003703184200200041186a410841001081808080001a200041" - "186a41084102200041086a41084100108a808080001a41f286c080004114200041086a4108" - "1083808080001a418687c080004138200041186a41084100200041086a41084100108a8080" - "8000ac108b808080001a41be87c0800041184100410041001080808080001a200042003703" - "084209200041086a410841001081808080001a20004200370310200041086a410841022000" - "41106a41084100108c808080001a41d687c080004112200041106a41081083808080001a20" - "0041086a41084103200041106a41084100108c808080001a41e887c080004112200041106a" - "41081083808080001a2000420037031842c0843d200041186a410841001081808080001a20" - "0041186a41084103200041106a41084100108c808080001a41fa87c080004118200041106a" - "41081083808080001a200041186a41084106200041106a41084100108c808080001a419288" - "c08000411c200041106a41081083808080001a41ae88c08000411741004100410010808080" - "80001a2000420037031042c0843d200041106a410841001081808080001a20004200370318" - "200041106a4108200041186a41084100108d808080001a41c588c080004114200041186a41" - "081083808080001a41d988c08000411a4100410041001080808080001a2000420037031841" - "e381c08000410841eb81c080004108200041186a410841001088808080001a0240024041eb" - "81c080004108200041186a41081085808080000d0041f388c0800041164100410041001080" - "808080001a0c010b418989c0800041154100410041001080808080001a0b41eb81c0800041" - "0841eb81c080004108200041186a410841001088808080001a0240024041e381c080004108" - "200041186a41081085808080000d00419e89c0800041174100410041001080808080001a0c" - "010b41b589c0800041164100410041001080808080001a0b41cb89c08000411a4100410041" - "001080808080001a2000420037031020004200370318420a200041186a4108410010818080" - "80001a41e381c080004108200041186a4108200041106a410841001089808080001a41e589" - "c080004119200041106a41081083808080001a41e381c080004108200041106a4108200041" - "106a410841001089808080001a41fe89c08000410f200041106a41081083808080001a0240" - "0240200041186a4108200041106a41081085808080000d00418d8ac0800041144100410041" - "001080808080001a0c010b41a18ac0800041134100410041001080808080001a0b20004120" - "6a24808080800041010b0bbe0a0100418080c0000bb40a0a24242420746573745f666c6f61" - "745f66726f6d5f7761736d202424242020666c6f61742066726f6d20693634203132333030" - "3a2020666c6f61742066726f6d206936342031323330303a206661696c65642020666c6f61" - "742066726f6d207536342031323330303a2020666c6f61742066726f6d2075363420313233" - "30303a206661696c65642020666c6f61742066726f6d2065787020322c206d616e74697373" - "61203132333a2020666c6f61742066726f6d2065787020322c206d616e746973736120333a" - "206661696c65642020666c6f61742066726f6d20636f6e737420313ad4838d7ea4c6800094" - "838d7ea4c680002020666c6f61742066726f6d20636f6e7374202d313a0a24242420746573" - "745f666c6f61745f636f6d70617265202424242020666c6f61742066726f6d20313a202066" - "6c6f61742066726f6d20313a206661696c65642020666c6f61742066726f6d2031203d3d20" - "464c4f41545f4f4e452020666c6f61742066726f6d203120213d20464c4f41545f4f4e4520" - "20666c6f61742066726f6d2031203e20464c4f41545f4e454741544956455f4f4e45202066" - "6c6f61742066726f6d203120213e20464c4f41545f4e454741544956455f4f4e452020464c" - "4f41545f4e454741544956455f4f4e45203c20666c6f61742066726f6d20312020464c4f41" - "545f4e454741544956455f4f4e4520213c20666c6f61742066726f6d20310a242424207465" - "73745f666c6f61745f6164645f737562747261637420242424202072657065617465642061" - "64643a20676f6f6420207265706561746564206164643a2062616420207265706561746564" - "2073756274726163743a20676f6f64202072657065617465642073756274726163743a2062" - "61640a24242420746573745f666c6f61745f6d756c7469706c795f64697669646520242424" - "20207265706561746564206d756c7469706c793a20676f6f6420207265706561746564206d" - "756c7469706c793a2062616420207265706561746564206469766964653a20676f6f642020" - "7265706561746564206469766964653a206261640a24242420746573745f666c6f61745f70" - "6f77202424242020666c6f61742063756265206f6620313a2020666c6f6174203674682070" - "6f776572206f66202d313a2020666c6f617420737175617265206f6620393a2020666c6f61" - "742030746820706f776572206f6620393a2020666c6f617420737175617265206f6620303a" - "2020666c6f61742030746820706f776572206f6620302028657870656374696e6720494e56" - "414c49445f504152414d53206572726f72293a0a24242420746573745f666c6f61745f726f" - "6f74202424242020666c6f61742073717274206f6620393a2020666c6f6174206362727420" - "6f6620393a2020666c6f61742063627274206f6620313030303030303a2020666c6f617420" - "36746820726f6f74206f6620313030303030303a0a24242420746573745f666c6f61745f6c" - "6f672024242420206c6f675f3130206f6620313030303030303a0a24242420746573745f66" - "6c6f61745f6e65676174652024242420206e656761746520636f6e737420313a20676f6f64" - "20206e656761746520636f6e737420313a2062616420206e656761746520636f6e7374202d" - "313a20676f6f6420206e656761746520636f6e7374202d313a206261640a24242420746573" - "745f666c6f61745f696e76657274202424242020696e76657274206120666c6f6174206672" - "6f6d2031303a2020696e7665727420616761696e3a2020696e766572742074776963653a20" - "676f6f642020696e766572742074776963653a20626164009c06046e616d65001110666c6f" - "61745f74657374732e7761736d01e1050f002b5f5a4e387872706c5f73746434686f737435" - "7472616365313768303332393563316538663365373233614501355f5a4e387872706c5f73" - "746434686f73743134666c6f61745f66726f6d5f696e743137683032306436373439326164" - "39346333304502365f5a4e387872706c5f73746434686f73743135666c6f61745f66726f6d" - "5f75696e74313768346166373638366538353062383432364503395f5a4e387872706c5f73" - "746434686f7374313874726163655f6f70617175655f666c6f617431376831396639386666" - "35663362313932336245042f5f5a4e387872706c5f73746434686f737439666c6f61745f73" - "6574313768323964346230383964626561326664624505345f5a4e387872706c5f73746434" - "686f73743133666c6f61745f636f6d70617265313768346362313239626634623330373233" - "6445062f5f5a4e387872706c5f73746434686f737439666c6f61745f616464313768383661" - "336165636435336234643937374507355f5a4e387872706c5f73746434686f73743134666c" - "6f61745f7375627472616374313768653033313036323931393464333931364508355f5a4e" - "387872706c5f73746434686f73743134666c6f61745f6d756c7469706c7931376830323839" - "3337633039656534323630644509335f5a4e387872706c5f73746434686f73743132666c6f" - "61745f64697669646531376834363036323038303562623237353632450a2f5f5a4e387872" - "706c5f73746434686f737439666c6f61745f706f7731376833326463303662646430303338" - "626331450b2f5f5a4e387872706c5f73746434686f73743974726163655f6e756d31376830" - "336535336633646539393463633033450c315f5a4e387872706c5f73746434686f73743130" - "666c6f61745f726f6f7431376863656632313139376565656136653630450d2f5f5a4e3878" - "72706c5f73746434686f737439666c6f61745f6c6f67313768323530663038303633353663" - "35653639450e0666696e697368071201000f5f5f737461636b5f706f696e746572090a0100" - "072e726f64617461004d0970726f64756365727302086c616e677561676501045275737400" - "0c70726f6365737365642d6279010572757374631d312e38382e3020283662303062633338" - "3820323032352d30362d3233290094010f7461726765745f6665617475726573082b0b6275" - "6c6b2d6d656d6f72792b0f62756c6b2d6d656d6f72792d6f70742b1663616c6c2d696e6469" - "726563742d6f7665726c6f6e672b0a6d756c746976616c75652b0f6d757461626c652d676c" - "6f62616c732b136e6f6e7472617070696e672d6670746f696e742b0f7265666572656e6365" - "2d74797065732b087369676e2d657874"; + "5f686561705f6261736503020af20e01ef0e01047f230041206b22012400418080c000411d" + "41004100410010001a200142003703100240428ce000200141106a22004108410010014108" + "460440419d80c00041172000410810021a41b480c000411e20004108410110001a0c010b41" + "d280c000411e41004100410010001a0b2001428ce0003703180240200141186a4108200141" + "106a2200410841001003410846044041f080c00041172000410810021a0c010b418781c000" + "411e41004100410010001a0b0240410242fb00200141106a22004108410010044108460440" + "41a581c00041212000410810021a0c010b41c681c000412641004100410010001a0b41ec81" + "c0004115418182c000410810021a419182c0004116418982c000410810021a41a782c00041" + "1b41004100410010001a2001420037031802404201200141186a2200410841001001410846" + "044041c282c000410f2000410810021a0c010b41d182c000411641004100410010001a0b02" + "40200141186a4108418182c0004108100545044041e782c000411b41004100410010001a0c" + "010b418283c000411b41004100410010001a0b0240200141186a4108418982c00041081005" + "4101460440419d83c000412341004100410010001a0c010b41c083c0004124410041004100" + "10001a0b0240418982c0004108200141186a41081005410246044041e483c0004123410041" + "00410010001a0c010b418784c000412441004100410010001a0b41ab84c000412041004100" + "410010001a200142d487b6f4c7d4b1c000370310410921000340200141106a220241084181" + "82c000410820024108410010061a200041016b22000d000b20014200370318420a20014118" + "6a22004108410010011a02402000410820024108100545044041cb84c00041144100410041" + "0010001a0c010b41df84c000411341004100410010001a0b410b21000340200141106a2202" + "4108418182c000410820024108410010071a200041016b22000d000b024020024108418982" + "c0004108100545044041f284c000411941004100410010001a0c010b418b85c00041184100" + "4100410010001a0b41a385c000412341004100410010001a20014200370300420a20014108" + "410010011a200142d487b6f4c7d4b1c000370308410621000340200141086a220241082001" + "410820024108410010081a200041016b22000d000b2001420037031042c0843d200141106a" + "22004108410010011a02402000410820024108100545044041c685c0004119410041004100" + "10001a0c010b41df85c000411841004100410010001a0b410721000340200141086a220241" + "082001410820024108410010091a200041016b22000d000b20014200370318417f42012001" + "41186a22004108410010041a02402002410820004108100545044041f785c0004117410041" + "00410010001a0c010b418e86c000411641004100410010001a0b41a486c000411741004100" + "410010001a20014200370308418182c00041084103200141086a220041084100100a1a41bb" + "86c00041122000410810021a418982c00041084106200041084100100a1a41cd86c0004118" + "2000410810021a200142003703104209200141106a22024108410010011a20024108410220" + "0041084100100a1a41e586c00041142000410810021a200241084100200041084100100a1a" + "41f986c00041172000410810021a200142003703184200200141186a22034108410010011a" + "200341084102200041084100100a1a419087c00041142000410810021a41a487c000413820" + "0341084100200041084100100aac100b1a41dc87c000411841004100410010001a20014200" + "370308420920004108410010011a20014200370310200041084102200241084100100c1a41" + "f487c00041122002410810021a200041084103200241084100100c1a418688c00041122002" + "410810021a2001420037031842c0843d20034108410010011a200341084103200241084100" + "100c1a419888c00041182002410810021a200341084106200241084100100c1a41b088c000" + "411c2002410810021a41cc88c000411741004100410010001a2001420037031042c0843d20" + "024108410010011a2001420037031820024108200341084100100d1a41e388c00041142003" + "410810021a41f788c000411a41004100410010001a20014200370318418182c00041084189" + "82c000410820034108410010081a0240418982c0004108200341081005450440419189c000" + "411641004100410010001a0c010b41a789c000411541004100410010001a0b418982c00041" + "08418982c0004108200141186a22004108410010081a0240418182c0004108200041081005" + "45044041bc89c000411741004100410010001a0c010b41d389c00041164100410041001000" + "1a0b41e989c000411a41004100410010001a2001420037031020014200370318420a200141" + "186a22024108410010011a418182c000410820024108200141106a22004108410010091a41" + "838ac00041192000410810021a418182c00041082000410820004108410010091a419c8ac0" + "00410f2000410810021a02402002410820004108100545044041ab8ac00041144100410041" + "0010001a0c010b41bf8ac000411341004100410010001a0b200141206a240041010b0bdc0a" + "0100418080c0000bd20a0a24242420746573745f666c6f61745f66726f6d5f7761736d2024" + "24242020666c6f61742066726f6d206936342031323330303a2020666c6f61742066726f6d" + "20693634203132333030206173204845583a2020666c6f61742066726f6d20693634203132" + "3330303a206661696c65642020666c6f61742066726f6d207536342031323330303a202066" + "6c6f61742066726f6d207536342031323330303a206661696c65642020666c6f6174206672" + "6f6d2065787020322c206d616e7469737361203132333a2020666c6f61742066726f6d2065" + "787020322c206d616e746973736120333a206661696c65642020666c6f61742066726f6d20" + "636f6e737420313ad4838d7ea4c6800094838d7ea4c680002020666c6f61742066726f6d20" + "636f6e7374202d313a0a24242420746573745f666c6f61745f636f6d706172652024242420" + "20666c6f61742066726f6d20313a2020666c6f61742066726f6d20313a206661696c656420" + "20666c6f61742066726f6d2031203d3d20464c4f41545f4f4e452020666c6f61742066726f" + "6d203120213d20464c4f41545f4f4e452020666c6f61742066726f6d2031203e20464c4f41" + "545f4e454741544956455f4f4e452020666c6f61742066726f6d203120213e20464c4f4154" + "5f4e454741544956455f4f4e452020464c4f41545f4e454741544956455f4f4e45203c2066" + "6c6f61742066726f6d20312020464c4f41545f4e454741544956455f4f4e4520213c20666c" + "6f61742066726f6d20310a24242420746573745f666c6f61745f6164645f73756274726163" + "742024242420207265706561746564206164643a20676f6f64202072657065617465642061" + "64643a20626164202072657065617465642073756274726163743a20676f6f642020726570" + "65617465642073756274726163743a206261640a24242420746573745f666c6f61745f6d75" + "6c7469706c795f6469766964652024242420207265706561746564206d756c7469706c793a" + "20676f6f6420207265706561746564206d756c7469706c793a206261642020726570656174" + "6564206469766964653a20676f6f6420207265706561746564206469766964653a20626164" + "0a24242420746573745f666c6f61745f706f77202424242020666c6f61742063756265206f" + "6620313a2020666c6f61742036746820706f776572206f66202d313a2020666c6f61742073" + "7175617265206f6620393a2020666c6f61742030746820706f776572206f6620393a202066" + "6c6f617420737175617265206f6620303a2020666c6f61742030746820706f776572206f66" + "20302028657870656374696e6720494e56414c49445f504152414d53206572726f72293a0a" + "24242420746573745f666c6f61745f726f6f74202424242020666c6f61742073717274206f" + "6620393a2020666c6f61742063627274206f6620393a2020666c6f61742063627274206f66" + "20313030303030303a2020666c6f61742036746820726f6f74206f6620313030303030303a" + "0a24242420746573745f666c6f61745f6c6f672024242420206c6f675f3130206f66203130" + "30303030303a0a24242420746573745f666c6f61745f6e65676174652024242420206e6567" + "61746520636f6e737420313a20676f6f6420206e656761746520636f6e737420313a206261" + "6420206e656761746520636f6e7374202d313a20676f6f6420206e656761746520636f6e73" + "74202d313a206261640a24242420746573745f666c6f61745f696e76657274202424242020" + "696e76657274206120666c6f61742066726f6d2031303a2020696e7665727420616761696e" + "3a2020696e766572742074776963653a20676f6f642020696e766572742074776963653a20" + "626164004d0970726f64756365727302086c616e6775616765010452757374000c70726f63" + "65737365642d6279010572757374631d312e39302e30202831313539653738633420323032" + "352d30392d313429002c0f7461726765745f6665617475726573022b0f6d757461626c652d" + "676c6f62616c732b087369676e2d657874"; extern std::string const float0Hex = "0061736d0100000001290560057f7f7f7f7f017f60047e7f7f7f017f6007" From d67dcfe3c41218d6e09ce7dc73121c908ecc9cca Mon Sep 17 00:00:00 2001 From: Ed Hennis Date: Mon, 29 Sep 2025 17:31:42 -0400 Subject: [PATCH 3/6] refactor: Restructure Transactor::preflight to reduce boilerplate (#5592) * Restructures `Transactor::preflight` to create several functions that will remove the need for error-prone boilerplate code in derived classes' implementations of `preflight`. --- include/xrpl/protocol/Permissions.h | 3 + include/xrpl/protocol/TER.h | 3 +- src/libxrpl/protocol/Permissions.cpp | 21 ++- src/test/app/AMM_test.cpp | 6 +- src/test/rpc/AccountSet_test.cpp | 29 +++ src/xrpld/app/tx/detail/AMMBid.cpp | 20 +- src/xrpld/app/tx/detail/AMMBid.h | 3 + src/xrpld/app/tx/detail/AMMClawback.cpp | 20 +- src/xrpld/app/tx/detail/AMMClawback.h | 3 + src/xrpld/app/tx/detail/AMMCreate.cpp | 22 +-- src/xrpld/app/tx/detail/AMMCreate.h | 3 + src/xrpld/app/tx/detail/AMMDelete.cpp | 20 +- src/xrpld/app/tx/detail/AMMDelete.h | 3 + src/xrpld/app/tx/detail/AMMDeposit.cpp | 26 +-- src/xrpld/app/tx/detail/AMMDeposit.h | 6 + src/xrpld/app/tx/detail/AMMVote.cpp | 20 +- src/xrpld/app/tx/detail/AMMVote.h | 3 + src/xrpld/app/tx/detail/AMMWithdraw.cpp | 25 +-- src/xrpld/app/tx/detail/AMMWithdraw.h | 6 + src/xrpld/app/tx/detail/Batch.cpp | 43 +++-- src/xrpld/app/tx/detail/Batch.h | 6 + src/xrpld/app/tx/detail/CancelCheck.cpp | 16 +- src/xrpld/app/tx/detail/CancelOffer.cpp | 14 +- src/xrpld/app/tx/detail/CashCheck.cpp | 16 +- src/xrpld/app/tx/detail/Change.cpp | 7 +- src/xrpld/app/tx/detail/Change.h | 3 - src/xrpld/app/tx/detail/Clawback.cpp | 17 +- src/xrpld/app/tx/detail/Clawback.h | 3 + src/xrpld/app/tx/detail/CreateCheck.cpp | 15 +- src/xrpld/app/tx/detail/CreateOffer.cpp | 36 ++-- src/xrpld/app/tx/detail/CreateOffer.h | 6 + src/xrpld/app/tx/detail/CreateTicket.cpp | 11 +- src/xrpld/app/tx/detail/Credentials.cpp | 76 +++----- src/xrpld/app/tx/detail/Credentials.h | 9 + src/xrpld/app/tx/detail/DID.cpp | 22 +-- src/xrpld/app/tx/detail/DelegateSet.cpp | 8 +- src/xrpld/app/tx/detail/DeleteAccount.cpp | 22 +-- src/xrpld/app/tx/detail/DeleteAccount.h | 3 + src/xrpld/app/tx/detail/DeleteOracle.cpp | 14 +- src/xrpld/app/tx/detail/DepositPreauth.cpp | 33 ++-- src/xrpld/app/tx/detail/DepositPreauth.h | 3 + src/xrpld/app/tx/detail/Escrow.cpp | 69 +++---- src/xrpld/app/tx/detail/Escrow.h | 15 ++ src/xrpld/app/tx/detail/LedgerStateFix.cpp | 13 +- src/xrpld/app/tx/detail/MPTokenAuthorize.cpp | 17 +- src/xrpld/app/tx/detail/MPTokenAuthorize.h | 3 + .../app/tx/detail/MPTokenIssuanceCreate.cpp | 32 ++-- .../app/tx/detail/MPTokenIssuanceCreate.h | 6 + .../app/tx/detail/MPTokenIssuanceDestroy.cpp | 18 +- .../app/tx/detail/MPTokenIssuanceDestroy.h | 3 + .../app/tx/detail/MPTokenIssuanceSet.cpp | 32 ++-- src/xrpld/app/tx/detail/MPTokenIssuanceSet.h | 6 + .../app/tx/detail/NFTokenAcceptOffer.cpp | 17 +- src/xrpld/app/tx/detail/NFTokenAcceptOffer.h | 3 + src/xrpld/app/tx/detail/NFTokenBurn.cpp | 11 +- .../app/tx/detail/NFTokenCancelOffer.cpp | 17 +- src/xrpld/app/tx/detail/NFTokenCancelOffer.h | 3 + .../app/tx/detail/NFTokenCreateOffer.cpp | 17 +- src/xrpld/app/tx/detail/NFTokenCreateOffer.h | 3 + src/xrpld/app/tx/detail/NFTokenMint.cpp | 36 ++-- src/xrpld/app/tx/detail/NFTokenMint.h | 6 + src/xrpld/app/tx/detail/NFTokenModify.cpp | 18 +- src/xrpld/app/tx/detail/NFTokenModify.h | 3 + src/xrpld/app/tx/detail/PayChan.cpp | 56 +++--- src/xrpld/app/tx/detail/PayChan.h | 12 ++ src/xrpld/app/tx/detail/Payment.cpp | 37 ++-- src/xrpld/app/tx/detail/Payment.h | 6 + .../tx/detail/PermissionedDomainDelete.cpp | 14 +- .../app/tx/detail/PermissionedDomainSet.cpp | 21 +-- .../app/tx/detail/PermissionedDomainSet.h | 3 + src/xrpld/app/tx/detail/SetAccount.cpp | 17 +- src/xrpld/app/tx/detail/SetAccount.h | 3 + src/xrpld/app/tx/detail/SetOracle.cpp | 11 +- src/xrpld/app/tx/detail/SetRegularKey.cpp | 14 +- src/xrpld/app/tx/detail/SetSignerList.cpp | 19 +- src/xrpld/app/tx/detail/SetSignerList.h | 3 + src/xrpld/app/tx/detail/SetTrust.cpp | 17 +- src/xrpld/app/tx/detail/SetTrust.h | 3 + src/xrpld/app/tx/detail/Transactor.cpp | 171 +++++++++++++----- src/xrpld/app/tx/detail/Transactor.h | 162 ++++++++++++++++- src/xrpld/app/tx/detail/VaultClawback.cpp | 11 +- src/xrpld/app/tx/detail/VaultCreate.cpp | 69 +++---- src/xrpld/app/tx/detail/VaultCreate.h | 6 + src/xrpld/app/tx/detail/VaultDelete.cpp | 11 +- src/xrpld/app/tx/detail/VaultDeposit.cpp | 11 +- src/xrpld/app/tx/detail/VaultSet.cpp | 22 +-- src/xrpld/app/tx/detail/VaultSet.h | 3 + src/xrpld/app/tx/detail/VaultWithdraw.cpp | 11 +- src/xrpld/app/tx/detail/XChainBridge.cpp | 89 ++------- src/xrpld/app/tx/detail/XChainBridge.h | 3 + src/xrpld/app/tx/detail/applySteps.cpp | 2 +- 91 files changed, 936 insertions(+), 844 deletions(-) diff --git a/include/xrpl/protocol/Permissions.h b/include/xrpl/protocol/Permissions.h index 2eca441124..d3f5253cd0 100644 --- a/include/xrpl/protocol/Permissions.h +++ b/include/xrpl/protocol/Permissions.h @@ -86,6 +86,9 @@ public: std::optional getGranularTxType(GranularPermissionType const& gpType) const; + std::optional> const + getTxFeature(TxType txType) const; + bool isDelegatable(std::uint32_t const& permissionValue, Rules const& rules) const; diff --git a/include/xrpl/protocol/TER.h b/include/xrpl/protocol/TER.h index 9ace6b80f8..0a3a3b999e 100644 --- a/include/xrpl/protocol/TER.h +++ b/include/xrpl/protocol/TER.h @@ -673,7 +673,8 @@ isTerRetry(TER x) noexcept inline bool isTesSuccess(TER x) noexcept { - return (x == tesSUCCESS); + // Makes use of TERSubset::operator bool() + return !(x); } inline bool diff --git a/src/libxrpl/protocol/Permissions.cpp b/src/libxrpl/protocol/Permissions.cpp index 6a4b0678e0..c9e32c5056 100644 --- a/src/libxrpl/protocol/Permissions.cpp +++ b/src/libxrpl/protocol/Permissions.cpp @@ -147,6 +147,19 @@ Permission::getGranularTxType(GranularPermissionType const& gpType) const return std::nullopt; } +std::optional> const +Permission::getTxFeature(TxType txType) const +{ + auto const txFeaturesIt = txFeatureMap_.find(txType); + XRPL_ASSERT( + txFeaturesIt != txFeatureMap_.end(), + "ripple::Permissions::getTxFeature : tx exists in txFeatureMap_"); + + if (txFeaturesIt->second == uint256{}) + return std::nullopt; + return txFeaturesIt->second; +} + bool Permission::isDelegatable( std::uint32_t const& permissionValue, @@ -166,16 +179,12 @@ Permission::isDelegatable( if (it == delegatableTx_.end()) return false; - auto const txFeaturesIt = txFeatureMap_.find(txType); - XRPL_ASSERT( - txFeaturesIt != txFeatureMap_.end(), - "ripple::Permissions::isDelegatable : tx exists in txFeatureMap_"); + auto const feature = getTxFeature(txType); // fixDelegateV1_1: Delegation is only allowed if the required amendment // for the transaction is enabled. For transactions that do not require // an amendment, delegation is always allowed. - if (txFeaturesIt->second != uint256{} && - !rules.enabled(txFeaturesIt->second)) + if (feature && !rules.enabled(*feature)) return false; } diff --git a/src/test/app/AMM_test.cpp b/src/test/app/AMM_test.cpp index cfe1ffab16..1fe37bb7c1 100644 --- a/src/test/app/AMM_test.cpp +++ b/src/test/app/AMM_test.cpp @@ -3572,7 +3572,7 @@ private: env.current()->rules(), tapNONE, env.journal); - auto pf = AMMBid::preflight(pfctx); + auto pf = Transactor::invokePreflight(pfctx); BEAST_EXPECT(pf == temDISABLED); env.app().config().features.insert(featureAMM); } @@ -3587,7 +3587,7 @@ private: env.current()->rules(), tapNONE, env.journal); - auto pf = AMMBid::preflight(pfctx); + auto pf = Transactor::invokePreflight(pfctx); BEAST_EXPECT(pf != tesSUCCESS); } @@ -3602,7 +3602,7 @@ private: env.current()->rules(), tapNONE, env.journal); - auto pf = AMMBid::preflight(pfctx); + auto pf = Transactor::invokePreflight(pfctx); BEAST_EXPECT(pf == temBAD_AMM_TOKENS); } } diff --git a/src/test/rpc/AccountSet_test.cpp b/src/test/rpc/AccountSet_test.cpp index 3615a715cd..52dc331a2b 100644 --- a/src/test/rpc/AccountSet_test.cpp +++ b/src/test/rpc/AccountSet_test.cpp @@ -19,6 +19,8 @@ #include +#include + #include #include #include @@ -578,6 +580,32 @@ public: env.close(); } + void + testBadSigningKey() + { + using namespace test::jtx; + testcase("Bad signing key"); + Env env(*this); + Account const alice("alice"); + + env.fund(XRP(10000), alice); + env.close(); + + auto jtx = env.jt(noop("alice"), ter(temBAD_SIGNATURE)); + if (!BEAST_EXPECT(jtx.stx)) + return; + auto stx = std::make_shared(*jtx.stx); + stx->at(sfSigningPubKey) = makeSlice(std::string("badkey")); + + env.app().openLedger().modify([&](OpenView& view, beast::Journal j) { + auto const result = + ripple::apply(env.app(), view, *stx, tapNONE, j); + BEAST_EXPECT(result.ter == temBAD_SIGNATURE); + BEAST_EXPECT(!result.applied); + return result.applied; + }); + } + void run() override { @@ -594,6 +622,7 @@ public: testRequireAuthWithDir(); testTransferRate(); testTicket(); + testBadSigningKey(); } }; diff --git a/src/xrpld/app/tx/detail/AMMBid.cpp b/src/xrpld/app/tx/detail/AMMBid.cpp index 806c075c4f..769668b07b 100644 --- a/src/xrpld/app/tx/detail/AMMBid.cpp +++ b/src/xrpld/app/tx/detail/AMMBid.cpp @@ -30,21 +30,15 @@ namespace ripple { +bool +AMMBid::checkExtraFeatures(PreflightContext const& ctx) +{ + return ammEnabled(ctx.rules); +} + NotTEC AMMBid::preflight(PreflightContext const& ctx) { - if (!ammEnabled(ctx.rules)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfUniversalMask) - { - JLOG(ctx.j.debug()) << "AMM Bid: invalid flags."; - return temINVALID_FLAG; - } - if (auto const res = invalidAMMAssetPair( ctx.tx[sfAsset].get(), ctx.tx[sfAsset2].get())) { @@ -95,7 +89,7 @@ AMMBid::preflight(PreflightContext const& ctx) } } - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/AMMBid.h b/src/xrpld/app/tx/detail/AMMBid.h index 4bb3a2adfd..4a527b6a93 100644 --- a/src/xrpld/app/tx/detail/AMMBid.h +++ b/src/xrpld/app/tx/detail/AMMBid.h @@ -71,6 +71,9 @@ public: { } + static bool + checkExtraFeatures(PreflightContext const& ctx); + static NotTEC preflight(PreflightContext const& ctx); diff --git a/src/xrpld/app/tx/detail/AMMClawback.cpp b/src/xrpld/app/tx/detail/AMMClawback.cpp index 634b948a64..9a79c94a58 100644 --- a/src/xrpld/app/tx/detail/AMMClawback.cpp +++ b/src/xrpld/app/tx/detail/AMMClawback.cpp @@ -33,19 +33,15 @@ namespace ripple { +std::uint32_t +AMMClawback::getFlagsMask(PreflightContext const& ctx) +{ + return tfAMMClawbackMask; +} + NotTEC AMMClawback::preflight(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureAMMClawback)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; // LCOV_EXCL_LINE - - auto const flags = ctx.tx.getFlags(); - if (flags & tfAMMClawbackMask) - return temINVALID_FLAG; - AccountID const issuer = ctx.tx[sfAccount]; AccountID const holder = ctx.tx[sfHolder]; @@ -63,6 +59,8 @@ AMMClawback::preflight(PreflightContext const& ctx) if (isXRP(asset)) return temMALFORMED; + auto const flags = ctx.tx.getFlags(); + if (flags & tfClawTwoAssets && asset.account != asset2.account) { JLOG(ctx.j.trace()) @@ -88,7 +86,7 @@ AMMClawback::preflight(PreflightContext const& ctx) if (clawAmount && *clawAmount <= beast::zero) return temBAD_AMOUNT; - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/AMMClawback.h b/src/xrpld/app/tx/detail/AMMClawback.h index fdcfc53e2c..1984937971 100644 --- a/src/xrpld/app/tx/detail/AMMClawback.h +++ b/src/xrpld/app/tx/detail/AMMClawback.h @@ -33,6 +33,9 @@ public: { } + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC preflight(PreflightContext const& ctx); diff --git a/src/xrpld/app/tx/detail/AMMCreate.cpp b/src/xrpld/app/tx/detail/AMMCreate.cpp index 03c972f1cd..63e20b42fb 100644 --- a/src/xrpld/app/tx/detail/AMMCreate.cpp +++ b/src/xrpld/app/tx/detail/AMMCreate.cpp @@ -31,21 +31,15 @@ namespace ripple { +bool +AMMCreate::checkExtraFeatures(PreflightContext const& ctx) +{ + return ammEnabled(ctx.rules); +} + NotTEC AMMCreate::preflight(PreflightContext const& ctx) { - if (!ammEnabled(ctx.rules)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfUniversalMask) - { - JLOG(ctx.j.debug()) << "AMM Instance: invalid flags."; - return temINVALID_FLAG; - } - auto const amount = ctx.tx[sfAmount]; auto const amount2 = ctx.tx[sfAmount2]; @@ -74,14 +68,14 @@ AMMCreate::preflight(PreflightContext const& ctx) return temBAD_FEE; } - return preflight2(ctx); + return tesSUCCESS; } XRPAmount AMMCreate::calculateBaseFee(ReadView const& view, STTx const& tx) { // The fee required for AMMCreate is one owner reserve. - return view.fees().increment; + return calculateOwnerReserveFee(view, tx); } TER diff --git a/src/xrpld/app/tx/detail/AMMCreate.h b/src/xrpld/app/tx/detail/AMMCreate.h index 189d66a55a..98231e5554 100644 --- a/src/xrpld/app/tx/detail/AMMCreate.h +++ b/src/xrpld/app/tx/detail/AMMCreate.h @@ -63,6 +63,9 @@ public: { } + static bool + checkExtraFeatures(PreflightContext const& ctx); + static NotTEC preflight(PreflightContext const& ctx); diff --git a/src/xrpld/app/tx/detail/AMMDelete.cpp b/src/xrpld/app/tx/detail/AMMDelete.cpp index 004e0b2229..663a4c4b0a 100644 --- a/src/xrpld/app/tx/detail/AMMDelete.cpp +++ b/src/xrpld/app/tx/detail/AMMDelete.cpp @@ -27,22 +27,16 @@ namespace ripple { +bool +AMMDelete::checkExtraFeatures(PreflightContext const& ctx) +{ + return ammEnabled(ctx.rules); +} + NotTEC AMMDelete::preflight(PreflightContext const& ctx) { - if (!ammEnabled(ctx.rules)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfUniversalMask) - { - JLOG(ctx.j.debug()) << "AMM Delete: invalid flags."; - return temINVALID_FLAG; - } - - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/AMMDelete.h b/src/xrpld/app/tx/detail/AMMDelete.h index 19885b1dad..36dace2e18 100644 --- a/src/xrpld/app/tx/detail/AMMDelete.h +++ b/src/xrpld/app/tx/detail/AMMDelete.h @@ -39,6 +39,9 @@ public: { } + static bool + checkExtraFeatures(PreflightContext const& ctx); + static NotTEC preflight(PreflightContext const& ctx); diff --git a/src/xrpld/app/tx/detail/AMMDeposit.cpp b/src/xrpld/app/tx/detail/AMMDeposit.cpp index 614d788c71..8a3e50ed63 100644 --- a/src/xrpld/app/tx/detail/AMMDeposit.cpp +++ b/src/xrpld/app/tx/detail/AMMDeposit.cpp @@ -29,21 +29,23 @@ namespace ripple { +bool +AMMDeposit::checkExtraFeatures(PreflightContext const& ctx) +{ + return ammEnabled(ctx.rules); +} + +std::uint32_t +AMMDeposit::getFlagsMask(PreflightContext const& ctx) + +{ + return tfDepositMask; +} + NotTEC AMMDeposit::preflight(PreflightContext const& ctx) { - if (!ammEnabled(ctx.rules)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - auto const flags = ctx.tx.getFlags(); - if (flags & tfDepositMask) - { - JLOG(ctx.j.debug()) << "AMM Deposit: invalid flags."; - return temINVALID_FLAG; - } auto const amount = ctx.tx[~sfAmount]; auto const amount2 = ctx.tx[~sfAmount2]; @@ -159,7 +161,7 @@ AMMDeposit::preflight(PreflightContext const& ctx) return temBAD_FEE; } - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/AMMDeposit.h b/src/xrpld/app/tx/detail/AMMDeposit.h index 0acb1dd9ab..c1a37be452 100644 --- a/src/xrpld/app/tx/detail/AMMDeposit.h +++ b/src/xrpld/app/tx/detail/AMMDeposit.h @@ -68,6 +68,12 @@ public: { } + static bool + checkExtraFeatures(PreflightContext const& ctx); + + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC preflight(PreflightContext const& ctx); diff --git a/src/xrpld/app/tx/detail/AMMVote.cpp b/src/xrpld/app/tx/detail/AMMVote.cpp index 6fbff86056..0ffbb38b37 100644 --- a/src/xrpld/app/tx/detail/AMMVote.cpp +++ b/src/xrpld/app/tx/detail/AMMVote.cpp @@ -27,15 +27,15 @@ namespace ripple { +bool +AMMVote::checkExtraFeatures(PreflightContext const& ctx) +{ + return ammEnabled(ctx.rules); +} + NotTEC AMMVote::preflight(PreflightContext const& ctx) { - if (!ammEnabled(ctx.rules)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - if (auto const res = invalidAMMAssetPair( ctx.tx[sfAsset].get(), ctx.tx[sfAsset2].get())) { @@ -43,19 +43,13 @@ AMMVote::preflight(PreflightContext const& ctx) return res; } - if (ctx.tx.getFlags() & tfUniversalMask) - { - JLOG(ctx.j.debug()) << "AMM Vote: invalid flags."; - return temINVALID_FLAG; - } - if (ctx.tx[sfTradingFee] > TRADING_FEE_THRESHOLD) { JLOG(ctx.j.debug()) << "AMM Vote: invalid trading fee."; return temBAD_FEE; } - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/AMMVote.h b/src/xrpld/app/tx/detail/AMMVote.h index 2bee01aff5..dc99480111 100644 --- a/src/xrpld/app/tx/detail/AMMVote.h +++ b/src/xrpld/app/tx/detail/AMMVote.h @@ -56,6 +56,9 @@ public: { } + static bool + checkExtraFeatures(PreflightContext const& ctx); + static NotTEC preflight(PreflightContext const& ctx); diff --git a/src/xrpld/app/tx/detail/AMMWithdraw.cpp b/src/xrpld/app/tx/detail/AMMWithdraw.cpp index 9bc36efc81..f5af9dfb9c 100644 --- a/src/xrpld/app/tx/detail/AMMWithdraw.cpp +++ b/src/xrpld/app/tx/detail/AMMWithdraw.cpp @@ -28,21 +28,22 @@ namespace ripple { +bool +AMMWithdraw::checkExtraFeatures(PreflightContext const& ctx) +{ + return ammEnabled(ctx.rules); +} + +std::uint32_t +AMMWithdraw::getFlagsMask(PreflightContext const& ctx) +{ + return tfWithdrawMask; +} + NotTEC AMMWithdraw::preflight(PreflightContext const& ctx) { - if (!ammEnabled(ctx.rules)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - auto const flags = ctx.tx.getFlags(); - if (flags & tfWithdrawMask) - { - JLOG(ctx.j.debug()) << "AMM Withdraw: invalid flags."; - return temINVALID_FLAG; - } auto const amount = ctx.tx[~sfAmount]; auto const amount2 = ctx.tx[~sfAmount2]; @@ -150,7 +151,7 @@ AMMWithdraw::preflight(PreflightContext const& ctx) } } - return preflight2(ctx); + return tesSUCCESS; } static std::optional diff --git a/src/xrpld/app/tx/detail/AMMWithdraw.h b/src/xrpld/app/tx/detail/AMMWithdraw.h index e9a597bdb7..31a7904626 100644 --- a/src/xrpld/app/tx/detail/AMMWithdraw.h +++ b/src/xrpld/app/tx/detail/AMMWithdraw.h @@ -76,6 +76,12 @@ public: { } + static bool + checkExtraFeatures(PreflightContext const& ctx); + + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC preflight(PreflightContext const& ctx); diff --git a/src/xrpld/app/tx/detail/Batch.cpp b/src/xrpld/app/tx/detail/Batch.cpp index 86d6e8a8f4..cba89348d0 100644 --- a/src/xrpld/app/tx/detail/Batch.cpp +++ b/src/xrpld/app/tx/detail/Batch.cpp @@ -164,6 +164,12 @@ Batch::calculateBaseFee(ReadView const& view, STTx const& tx) return signerFees + txnFees + batchBase; } +std::uint32_t +Batch::getFlagsMask(PreflightContext const& ctx) +{ + return tfBatchMask; +} + /** * @brief Performs preflight validation checks for a Batch transaction. * @@ -200,23 +206,9 @@ Batch::calculateBaseFee(ReadView const& view, STTx const& tx) NotTEC Batch::preflight(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureBatch)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - auto const parentBatchId = ctx.tx.getTransactionID(); - auto const outerAccount = ctx.tx.getAccountID(sfAccount); auto const flags = ctx.tx.getFlags(); - if (flags & tfBatchMask) - { - JLOG(ctx.j.debug()) << "BatchTrace[" << parentBatchId << "]:" - << "invalid flags."; - return temINVALID_FLAG; - } - if (std::popcount( flags & (tfAllOrNothing | tfOnlyOne | tfUntilFailure | tfIndependent)) != 1) @@ -242,7 +234,6 @@ Batch::preflight(PreflightContext const& ctx) } // Validation Inner Batch Txns - std::unordered_set requiredSigners; std::unordered_set uniqueHashes; std::unordered_map> accountSeqTicket; @@ -372,6 +363,23 @@ Batch::preflight(PreflightContext const& ctx) } } } + } + + return tesSUCCESS; +} + +NotTEC +Batch::preflightSigValidated(PreflightContext const& ctx) +{ + auto const parentBatchId = ctx.tx.getTransactionID(); + auto const outerAccount = ctx.tx.getAccountID(sfAccount); + auto const& rawTxns = ctx.tx.getFieldArray(sfRawTransactions); + + // Build the signers list + std::unordered_set requiredSigners; + for (STObject const& rb : rawTxns) + { + auto const innerAccount = rb.getAccountID(sfAccount); // If the inner account is the same as the outer account, do not add the // inner account to the required signers set. @@ -379,11 +387,6 @@ Batch::preflight(PreflightContext const& ctx) requiredSigners.insert(innerAccount); } - // LCOV_EXCL_START - if (auto const ret = preflight2(ctx); !isTesSuccess(ret)) - return ret; - // LCOV_EXCL_STOP - // Validation Batch Signers std::unordered_set batchSigners; if (ctx.tx.isFieldPresent(sfBatchSigners)) diff --git a/src/xrpld/app/tx/detail/Batch.h b/src/xrpld/app/tx/detail/Batch.h index 211bce0589..07863a5f33 100644 --- a/src/xrpld/app/tx/detail/Batch.h +++ b/src/xrpld/app/tx/detail/Batch.h @@ -40,9 +40,15 @@ public: static XRPAmount calculateBaseFee(ReadView const& view, STTx const& tx); + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC preflight(PreflightContext const& ctx); + static NotTEC + preflightSigValidated(PreflightContext const& ctx); + static NotTEC checkSign(PreclaimContext const& ctx); diff --git a/src/xrpld/app/tx/detail/CancelCheck.cpp b/src/xrpld/app/tx/detail/CancelCheck.cpp index 39d0d23096..f1a9b42a89 100644 --- a/src/xrpld/app/tx/detail/CancelCheck.cpp +++ b/src/xrpld/app/tx/detail/CancelCheck.cpp @@ -32,21 +32,7 @@ namespace ripple { NotTEC CancelCheck::preflight(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureChecks)) - return temDISABLED; - - NotTEC const ret{preflight1(ctx)}; - if (!isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfUniversalMask) - { - // There are no flags (other than universal) for CreateCheck yet. - JLOG(ctx.j.warn()) << "Malformed transaction: Invalid flags set."; - return temINVALID_FLAG; - } - - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/CancelOffer.cpp b/src/xrpld/app/tx/detail/CancelOffer.cpp index e0a5c7baa7..e7ec28ce17 100644 --- a/src/xrpld/app/tx/detail/CancelOffer.cpp +++ b/src/xrpld/app/tx/detail/CancelOffer.cpp @@ -28,25 +28,13 @@ namespace ripple { NotTEC CancelOffer::preflight(PreflightContext const& ctx) { - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - auto const uTxFlags = ctx.tx.getFlags(); - - if (uTxFlags & tfUniversalMask) - { - JLOG(ctx.j.trace()) << "Malformed transaction: " - << "Invalid flags set."; - return temINVALID_FLAG; - } - if (!ctx.tx[sfOfferSequence]) { JLOG(ctx.j.trace()) << "CancelOffer::preflight: missing sequence"; return temBAD_SEQUENCE; } - return preflight2(ctx); + return tesSUCCESS; } //------------------------------------------------------------------------------ diff --git a/src/xrpld/app/tx/detail/CashCheck.cpp b/src/xrpld/app/tx/detail/CashCheck.cpp index 0f1d08689c..f8ab6189a3 100644 --- a/src/xrpld/app/tx/detail/CashCheck.cpp +++ b/src/xrpld/app/tx/detail/CashCheck.cpp @@ -35,20 +35,6 @@ namespace ripple { NotTEC CashCheck::preflight(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureChecks)) - return temDISABLED; - - NotTEC const ret{preflight1(ctx)}; - if (!isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfUniversalMask) - { - // There are no flags (other than universal) for CashCheck yet. - JLOG(ctx.j.warn()) << "Malformed transaction: Invalid flags set."; - return temINVALID_FLAG; - } - // Exactly one of Amount or DeliverMin must be present. auto const optAmount = ctx.tx[~sfAmount]; auto const optDeliverMin = ctx.tx[~sfDeliverMin]; @@ -76,7 +62,7 @@ CashCheck::preflight(PreflightContext const& ctx) return temBAD_CURRENCY; } - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/Change.cpp b/src/xrpld/app/tx/detail/Change.cpp index de30ed5f62..d6a31024f3 100644 --- a/src/xrpld/app/tx/detail/Change.cpp +++ b/src/xrpld/app/tx/detail/Change.cpp @@ -33,11 +33,12 @@ namespace ripple { +template <> NotTEC -Change::preflight(PreflightContext const& ctx) +Transactor::invokePreflight(PreflightContext const& ctx) { - auto const ret = preflight0(ctx); - if (!isTesSuccess(ret)) + // 0 means "Allow any flags" + if (auto const ret = preflight0(ctx, 0)) return ret; auto account = ctx.tx.getAccountID(sfAccount); diff --git a/src/xrpld/app/tx/detail/Change.h b/src/xrpld/app/tx/detail/Change.h index d710827dd6..7b8fbf3421 100644 --- a/src/xrpld/app/tx/detail/Change.h +++ b/src/xrpld/app/tx/detail/Change.h @@ -33,9 +33,6 @@ public: { } - static NotTEC - preflight(PreflightContext const& ctx); - TER doApply() override; void diff --git a/src/xrpld/app/tx/detail/Clawback.cpp b/src/xrpld/app/tx/detail/Clawback.cpp index 08cf4baef0..b346e4a1c1 100644 --- a/src/xrpld/app/tx/detail/Clawback.cpp +++ b/src/xrpld/app/tx/detail/Clawback.cpp @@ -75,25 +75,22 @@ preflightHelper(PreflightContext const& ctx) return tesSUCCESS; } +std::uint32_t +Clawback::getFlagsMask(PreflightContext const& ctx) +{ + return tfClawbackMask; +} + NotTEC Clawback::preflight(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureClawback)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfClawbackMask) - return temINVALID_FLAG; - if (auto const ret = std::visit( [&](T const&) { return preflightHelper(ctx); }, ctx.tx[sfAmount].asset().value()); !isTesSuccess(ret)) return ret; - return preflight2(ctx); + return tesSUCCESS; } template diff --git a/src/xrpld/app/tx/detail/Clawback.h b/src/xrpld/app/tx/detail/Clawback.h index d908a2e4ef..b02233c2ed 100644 --- a/src/xrpld/app/tx/detail/Clawback.h +++ b/src/xrpld/app/tx/detail/Clawback.h @@ -33,6 +33,9 @@ public: { } + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC preflight(PreflightContext const& ctx); diff --git a/src/xrpld/app/tx/detail/CreateCheck.cpp b/src/xrpld/app/tx/detail/CreateCheck.cpp index 4dbfd1f81d..57f3a92255 100644 --- a/src/xrpld/app/tx/detail/CreateCheck.cpp +++ b/src/xrpld/app/tx/detail/CreateCheck.cpp @@ -31,19 +31,6 @@ namespace ripple { NotTEC CreateCheck::preflight(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureChecks)) - return temDISABLED; - - NotTEC const ret{preflight1(ctx)}; - if (!isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfUniversalMask) - { - // There are no flags (other than universal) for CreateCheck yet. - JLOG(ctx.j.warn()) << "Malformed transaction: Invalid flags set."; - return temINVALID_FLAG; - } if (ctx.tx[sfAccount] == ctx.tx[sfDestination]) { // They wrote a check to themselves. @@ -76,7 +63,7 @@ CreateCheck::preflight(PreflightContext const& ctx) } } - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/CreateOffer.cpp b/src/xrpld/app/tx/detail/CreateOffer.cpp index 6185e52183..86750eb51d 100644 --- a/src/xrpld/app/tx/detail/CreateOffer.cpp +++ b/src/xrpld/app/tx/detail/CreateOffer.cpp @@ -43,30 +43,36 @@ CreateOffer::makeTxConsequences(PreflightContext const& ctx) return TxConsequences{ctx.tx, calculateMaxXRPSpend(ctx.tx)}; } -NotTEC -CreateOffer::preflight(PreflightContext const& ctx) +bool +CreateOffer::checkExtraFeatures(PreflightContext const& ctx) { if (ctx.tx.isFieldPresent(sfDomainID) && !ctx.rules.enabled(featurePermissionedDEX)) - return temDISABLED; + return false; - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; + return true; +} +std::uint32_t +CreateOffer::getFlagsMask(PreflightContext const& ctx) +{ + // The tfOfferCreateMask is built assuming that PermissionedDEX is + // enabled + if (ctx.rules.enabled(featurePermissionedDEX)) + return tfOfferCreateMask; + // If PermissionedDEX is not enabled, add tfHybrid to the mask, + // indicating it is not allowed. + return tfOfferCreateMask | tfHybrid; +} + +NotTEC +CreateOffer::preflight(PreflightContext const& ctx) +{ auto& tx = ctx.tx; auto& j = ctx.j; std::uint32_t const uTxFlags = tx.getFlags(); - if (uTxFlags & tfOfferCreateMask) - { - JLOG(j.debug()) << "Malformed transaction: Invalid flags set."; - return temINVALID_FLAG; - } - - if (!ctx.rules.enabled(featurePermissionedDEX) && tx.isFlag(tfHybrid)) - return temINVALID_FLAG; - if (tx.isFlag(tfHybrid) && !tx.isFieldPresent(sfDomainID)) return temINVALID_FLAG; @@ -136,7 +142,7 @@ CreateOffer::preflight(PreflightContext const& ctx) return temBAD_ISSUER; } - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/CreateOffer.h b/src/xrpld/app/tx/detail/CreateOffer.h index 6e3d6145b1..c38e244b34 100644 --- a/src/xrpld/app/tx/detail/CreateOffer.h +++ b/src/xrpld/app/tx/detail/CreateOffer.h @@ -43,6 +43,12 @@ public: static TxConsequences makeTxConsequences(PreflightContext const& ctx); + static bool + checkExtraFeatures(PreflightContext const& ctx); + + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + /** Enforce constraints beyond those of the Transactor base class. */ static NotTEC preflight(PreflightContext const& ctx); diff --git a/src/xrpld/app/tx/detail/CreateTicket.cpp b/src/xrpld/app/tx/detail/CreateTicket.cpp index 594335f489..d48da2d780 100644 --- a/src/xrpld/app/tx/detail/CreateTicket.cpp +++ b/src/xrpld/app/tx/detail/CreateTicket.cpp @@ -36,20 +36,11 @@ CreateTicket::makeTxConsequences(PreflightContext const& ctx) NotTEC CreateTicket::preflight(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureTicketBatch)) - return temDISABLED; - - if (ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; - if (std::uint32_t const count = ctx.tx[sfTicketCount]; count < minValidCount || count > maxValidCount) return temINVALID_COUNT; - if (NotTEC const ret{preflight1(ctx)}; !isTesSuccess(ret)) - return ret; - - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/Credentials.cpp b/src/xrpld/app/tx/detail/Credentials.cpp index b30ae200b7..4b77163c5d 100644 --- a/src/xrpld/app/tx/detail/Credentials.cpp +++ b/src/xrpld/app/tx/detail/Credentials.cpp @@ -48,28 +48,19 @@ using namespace credentials; // ------- CREATE -------------------------- +std::uint32_t +CredentialCreate::getFlagsMask(PreflightContext const& ctx) +{ + // 0 means "Allow any flags" + return ctx.rules.enabled(fixInvalidTxFlags) ? tfUniversalMask : 0; +} + NotTEC CredentialCreate::preflight(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureCredentials)) - { - JLOG(ctx.j.trace()) << "featureCredentials is disabled."; - return temDISABLED; - } - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - auto const& tx = ctx.tx; auto& j = ctx.j; - if (ctx.rules.enabled(fixInvalidTxFlags) && - (tx.getFlags() & tfUniversalMask)) - { - JLOG(ctx.j.debug()) << "CredentialCreate: invalid flags."; - return temINVALID_FLAG; - } - if (!tx[sfSubject]) { JLOG(j.trace()) << "Malformed transaction: Invalid Subject"; @@ -91,7 +82,7 @@ CredentialCreate::preflight(PreflightContext const& ctx) return temMALFORMED; } - return preflight2(ctx); + return tesSUCCESS; } TER @@ -202,25 +193,17 @@ CredentialCreate::doApply() } // ------- DELETE -------------------------- + +std::uint32_t +CredentialDelete::getFlagsMask(PreflightContext const& ctx) +{ + // 0 means "Allow any flags" + return ctx.rules.enabled(fixInvalidTxFlags) ? tfUniversalMask : 0; +} + NotTEC CredentialDelete::preflight(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureCredentials)) - { - JLOG(ctx.j.trace()) << "featureCredentials is disabled."; - return temDISABLED; - } - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.rules.enabled(fixInvalidTxFlags) && - (ctx.tx.getFlags() & tfUniversalMask)) - { - JLOG(ctx.j.debug()) << "CredentialDelete: invalid flags."; - return temINVALID_FLAG; - } - auto const subject = ctx.tx[~sfSubject]; auto const issuer = ctx.tx[~sfIssuer]; @@ -248,7 +231,7 @@ CredentialDelete::preflight(PreflightContext const& ctx) return temMALFORMED; } - return preflight2(ctx); + return tesSUCCESS; } TER @@ -289,25 +272,16 @@ CredentialDelete::doApply() // ------- APPLY -------------------------- +std::uint32_t +CredentialAccept::getFlagsMask(PreflightContext const& ctx) +{ + // 0 means "Allow any flags" + return ctx.rules.enabled(fixInvalidTxFlags) ? tfUniversalMask : 0; +} + NotTEC CredentialAccept::preflight(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureCredentials)) - { - JLOG(ctx.j.trace()) << "featureCredentials is disabled."; - return temDISABLED; - } - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.rules.enabled(fixInvalidTxFlags) && - (ctx.tx.getFlags() & tfUniversalMask)) - { - JLOG(ctx.j.debug()) << "CredentialAccept: invalid flags."; - return temINVALID_FLAG; - } - if (!ctx.tx[sfIssuer]) { JLOG(ctx.j.trace()) << "Malformed transaction: Issuer field zeroed."; @@ -322,7 +296,7 @@ CredentialAccept::preflight(PreflightContext const& ctx) return temMALFORMED; } - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/Credentials.h b/src/xrpld/app/tx/detail/Credentials.h index 5b4acb3998..a5885a2226 100644 --- a/src/xrpld/app/tx/detail/Credentials.h +++ b/src/xrpld/app/tx/detail/Credentials.h @@ -33,6 +33,9 @@ public: { } + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC preflight(PreflightContext const& ctx); @@ -54,6 +57,9 @@ public: { } + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC preflight(PreflightContext const& ctx); @@ -75,6 +81,9 @@ public: { } + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC preflight(PreflightContext const& ctx); diff --git a/src/xrpld/app/tx/detail/DID.cpp b/src/xrpld/app/tx/detail/DID.cpp index 8c4a220844..b38b207d36 100644 --- a/src/xrpld/app/tx/detail/DID.cpp +++ b/src/xrpld/app/tx/detail/DID.cpp @@ -45,15 +45,6 @@ namespace ripple { NotTEC DIDSet::preflight(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureDID)) - return temDISABLED; - - if (ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - if (!ctx.tx.isFieldPresent(sfURI) && !ctx.tx.isFieldPresent(sfDIDDocument) && !ctx.tx.isFieldPresent(sfData)) return temEMPTY_DID; @@ -74,7 +65,7 @@ DIDSet::preflight(PreflightContext const& ctx) isTooLong(sfData, maxDIDAttestationLength)) return temMALFORMED; - return preflight2(ctx); + return tesSUCCESS; } TER @@ -174,16 +165,7 @@ DIDSet::doApply() NotTEC DIDDelete::preflight(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureDID)) - return temDISABLED; - - if (ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/DelegateSet.cpp b/src/xrpld/app/tx/detail/DelegateSet.cpp index 53052fd75b..e769f75d8a 100644 --- a/src/xrpld/app/tx/detail/DelegateSet.cpp +++ b/src/xrpld/app/tx/detail/DelegateSet.cpp @@ -30,12 +30,6 @@ namespace ripple { NotTEC DelegateSet::preflight(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featurePermissionDelegation)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - auto const& permissions = ctx.tx.getFieldArray(sfPermissions); if (permissions.size() > permissionMaxSize) return temARRAY_TOO_LARGE; @@ -57,7 +51,7 @@ DelegateSet::preflight(PreflightContext const& ctx) return temMALFORMED; } - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/DeleteAccount.cpp b/src/xrpld/app/tx/detail/DeleteAccount.cpp index 02f84adcc3..565d938c83 100644 --- a/src/xrpld/app/tx/detail/DeleteAccount.cpp +++ b/src/xrpld/app/tx/detail/DeleteAccount.cpp @@ -38,22 +38,22 @@ namespace ripple { -NotTEC -DeleteAccount::preflight(PreflightContext const& ctx) +bool +DeleteAccount::checkExtraFeatures(PreflightContext const& ctx) { if (!ctx.rules.enabled(featureDeletableAccounts)) - return temDISABLED; + return false; if (ctx.tx.isFieldPresent(sfCredentialIDs) && !ctx.rules.enabled(featureCredentials)) - return temDISABLED; + return false; - if (ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; + return true; +} +NotTEC +DeleteAccount::preflight(PreflightContext const& ctx) +{ if (ctx.tx[sfAccount] == ctx.tx[sfDestination]) // An account cannot be deleted and give itself the resulting XRP. return temDST_IS_SRC; @@ -62,14 +62,14 @@ DeleteAccount::preflight(PreflightContext const& ctx) !isTesSuccess(err)) return err; - return preflight2(ctx); + return tesSUCCESS; } XRPAmount DeleteAccount::calculateBaseFee(ReadView const& view, STTx const& tx) { // The fee required for AccountDelete is one owner reserve. - return view.fees().increment; + return calculateOwnerReserveFee(view, tx); } namespace { diff --git a/src/xrpld/app/tx/detail/DeleteAccount.h b/src/xrpld/app/tx/detail/DeleteAccount.h index c9d3305562..ee9db97d50 100644 --- a/src/xrpld/app/tx/detail/DeleteAccount.h +++ b/src/xrpld/app/tx/detail/DeleteAccount.h @@ -33,6 +33,9 @@ public: { } + static bool + checkExtraFeatures(PreflightContext const& ctx); + static NotTEC preflight(PreflightContext const& ctx); diff --git a/src/xrpld/app/tx/detail/DeleteOracle.cpp b/src/xrpld/app/tx/detail/DeleteOracle.cpp index ac195d100c..7dba477aaa 100644 --- a/src/xrpld/app/tx/detail/DeleteOracle.cpp +++ b/src/xrpld/app/tx/detail/DeleteOracle.cpp @@ -29,19 +29,7 @@ namespace ripple { NotTEC DeleteOracle::preflight(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featurePriceOracle)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfUniversalMask) - { - JLOG(ctx.j.debug()) << "Oracle Delete: invalid flags."; - return temINVALID_FLAG; - } - - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/DepositPreauth.cpp b/src/xrpld/app/tx/detail/DepositPreauth.cpp index 0e8c5c05d2..236b59a173 100644 --- a/src/xrpld/app/tx/detail/DepositPreauth.cpp +++ b/src/xrpld/app/tx/detail/DepositPreauth.cpp @@ -30,32 +30,29 @@ namespace ripple { +bool +DepositPreauth::checkExtraFeatures(PreflightContext const& ctx) +{ + bool const authArrPresent = ctx.tx.isFieldPresent(sfAuthorizeCredentials); + bool const unauthArrPresent = + ctx.tx.isFieldPresent(sfUnauthorizeCredentials); + bool const authCredPresent = authArrPresent || unauthArrPresent; + + if (authCredPresent && !ctx.rules.enabled(featureCredentials)) + return false; + + return true; +} + NotTEC DepositPreauth::preflight(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureDepositPreauth)) - return temDISABLED; - bool const authArrPresent = ctx.tx.isFieldPresent(sfAuthorizeCredentials); bool const unauthArrPresent = ctx.tx.isFieldPresent(sfUnauthorizeCredentials); int const authCredPresent = static_cast(authArrPresent) + static_cast(unauthArrPresent); - if (authCredPresent && !ctx.rules.enabled(featureCredentials)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - auto& tx = ctx.tx; - - if (tx.getFlags() & tfUniversalMask) - { - JLOG(ctx.j.trace()) << "Malformed transaction: Invalid flags set."; - return temINVALID_FLAG; - } - auto const optAuth = ctx.tx[~sfAuthorize]; auto const optUnauth = ctx.tx[~sfUnauthorize]; int const authPresent = static_cast(optAuth.has_value()) + @@ -102,7 +99,7 @@ DepositPreauth::preflight(PreflightContext const& ctx) return err; } - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/DepositPreauth.h b/src/xrpld/app/tx/detail/DepositPreauth.h index 76a7c08073..ead17742cd 100644 --- a/src/xrpld/app/tx/detail/DepositPreauth.h +++ b/src/xrpld/app/tx/detail/DepositPreauth.h @@ -33,6 +33,9 @@ public: { } + static bool + checkExtraFeatures(PreflightContext const& ctx); + static NotTEC preflight(PreflightContext const& ctx); diff --git a/src/xrpld/app/tx/detail/Escrow.cpp b/src/xrpld/app/tx/detail/Escrow.cpp index f1d1db79a0..969fd4dd4c 100644 --- a/src/xrpld/app/tx/detail/Escrow.cpp +++ b/src/xrpld/app/tx/detail/Escrow.cpp @@ -118,15 +118,16 @@ escrowCreatePreflightHelper(PreflightContext const& ctx) return tesSUCCESS; } +std::uint32_t +EscrowCreate::getFlagsMask(PreflightContext const& ctx) +{ + // 0 means "Allow any flags" + return ctx.rules.enabled(fix1543) ? tfUniversalMask : 0; +} + NotTEC EscrowCreate::preflight(PreflightContext const& ctx) { - if (ctx.rules.enabled(fix1543) && ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - STAmount const amount{ctx.tx[sfAmount]}; if (!isXRP(amount)) { @@ -189,7 +190,7 @@ EscrowCreate::preflight(PreflightContext const& ctx) return temDISABLED; } - return preflight2(ctx); + return tesSUCCESS; } template @@ -629,19 +630,23 @@ checkCondition(Slice f, Slice c) return validate(*fulfillment, *condition); } +bool +EscrowFinish::checkExtraFeatures(PreflightContext const& ctx) +{ + return !ctx.tx.isFieldPresent(sfCredentialIDs) || + ctx.rules.enabled(featureCredentials); +} + +std::uint32_t +EscrowFinish::getFlagsMask(PreflightContext const& ctx) +{ + // 0 means "Allow any flags" + return ctx.rules.enabled(fix1543) ? tfUniversalMask : 0; +} + NotTEC EscrowFinish::preflight(PreflightContext const& ctx) { - if (ctx.rules.enabled(fix1543) && ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; - - if (ctx.tx.isFieldPresent(sfCredentialIDs) && - !ctx.rules.enabled(featureCredentials)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - auto const cb = ctx.tx[~sfCondition]; auto const fb = ctx.tx[~sfFulfillment]; @@ -650,13 +655,14 @@ EscrowFinish::preflight(PreflightContext const& ctx) if (static_cast(cb) != static_cast(fb)) return temMALFORMED; - // Verify the transaction signature. If it doesn't work - // then don't do any more work. - { - auto const ret = preflight2(ctx); - if (!isTesSuccess(ret)) - return ret; - } + return tesSUCCESS; +} + +NotTEC +EscrowFinish::preflightSigValidated(PreflightContext const& ctx) +{ + auto const cb = ctx.tx[~sfCondition]; + auto const fb = ctx.tx[~sfFulfillment]; if (cb && fb) { @@ -1207,16 +1213,17 @@ EscrowFinish::doApply() //------------------------------------------------------------------------------ +std::uint32_t +EscrowCancel::getFlagsMask(PreflightContext const& ctx) +{ + // 0 means "Allow any flags" + return ctx.rules.enabled(fix1543) ? tfUniversalMask : 0; +} + NotTEC EscrowCancel::preflight(PreflightContext const& ctx) { - if (ctx.rules.enabled(fix1543) && ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - return preflight2(ctx); + return tesSUCCESS; } template diff --git a/src/xrpld/app/tx/detail/Escrow.h b/src/xrpld/app/tx/detail/Escrow.h index 2225c94f16..8956be2939 100644 --- a/src/xrpld/app/tx/detail/Escrow.h +++ b/src/xrpld/app/tx/detail/Escrow.h @@ -36,6 +36,9 @@ public: static TxConsequences makeTxConsequences(PreflightContext const& ctx); + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC preflight(PreflightContext const& ctx); @@ -57,9 +60,18 @@ public: { } + static bool + checkExtraFeatures(PreflightContext const& ctx); + + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC preflight(PreflightContext const& ctx); + static NotTEC + preflightSigValidated(PreflightContext const& ctx); + static XRPAmount calculateBaseFee(ReadView const& view, STTx const& tx); @@ -81,6 +93,9 @@ public: { } + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC preflight(PreflightContext const& ctx); diff --git a/src/xrpld/app/tx/detail/LedgerStateFix.cpp b/src/xrpld/app/tx/detail/LedgerStateFix.cpp index b861f1d0ef..6059e15313 100644 --- a/src/xrpld/app/tx/detail/LedgerStateFix.cpp +++ b/src/xrpld/app/tx/detail/LedgerStateFix.cpp @@ -30,15 +30,6 @@ namespace ripple { NotTEC LedgerStateFix::preflight(PreflightContext const& ctx) { - if (!ctx.rules.enabled(fixNFTokenPageLinks)) - return temDISABLED; - - if (ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - switch (ctx.tx[sfLedgerFixType]) { case FixType::nfTokenPageLink: @@ -50,7 +41,7 @@ LedgerStateFix::preflight(PreflightContext const& ctx) return tefINVALID_LEDGER_FIX_TYPE; } - return preflight2(ctx); + return tesSUCCESS; } XRPAmount @@ -58,7 +49,7 @@ LedgerStateFix::calculateBaseFee(ReadView const& view, STTx const& tx) { // The fee required for LedgerStateFix is one owner reserve, just like // the fee for AccountDelete. - return view.fees().increment; + return calculateOwnerReserveFee(view, tx); } TER diff --git a/src/xrpld/app/tx/detail/MPTokenAuthorize.cpp b/src/xrpld/app/tx/detail/MPTokenAuthorize.cpp index 1c6d153ec5..edeb12e5c0 100644 --- a/src/xrpld/app/tx/detail/MPTokenAuthorize.cpp +++ b/src/xrpld/app/tx/detail/MPTokenAuthorize.cpp @@ -26,22 +26,19 @@ namespace ripple { +std::uint32_t +MPTokenAuthorize::getFlagsMask(PreflightContext const& ctx) +{ + return tfMPTokenAuthorizeMask; +} + NotTEC MPTokenAuthorize::preflight(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureMPTokensV1)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfMPTokenAuthorizeMask) - return temINVALID_FLAG; - if (ctx.tx[sfAccount] == ctx.tx[~sfHolder]) return temMALFORMED; - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/MPTokenAuthorize.h b/src/xrpld/app/tx/detail/MPTokenAuthorize.h index 85e8edcf9f..43a962e24e 100644 --- a/src/xrpld/app/tx/detail/MPTokenAuthorize.h +++ b/src/xrpld/app/tx/detail/MPTokenAuthorize.h @@ -42,6 +42,9 @@ public: { } + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC preflight(PreflightContext const& ctx); diff --git a/src/xrpld/app/tx/detail/MPTokenIssuanceCreate.cpp b/src/xrpld/app/tx/detail/MPTokenIssuanceCreate.cpp index 478ef17bb0..eec4187573 100644 --- a/src/xrpld/app/tx/detail/MPTokenIssuanceCreate.cpp +++ b/src/xrpld/app/tx/detail/MPTokenIssuanceCreate.cpp @@ -25,31 +25,37 @@ namespace ripple { -NotTEC -MPTokenIssuanceCreate::preflight(PreflightContext const& ctx) +bool +MPTokenIssuanceCreate::checkExtraFeatures(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureMPTokensV1)) - return temDISABLED; - if (ctx.tx.isFieldPresent(sfDomainID) && !(ctx.rules.enabled(featurePermissionedDomains) && ctx.rules.enabled(featureSingleAssetVault))) - return temDISABLED; + return false; if (ctx.tx.isFieldPresent(sfMutableFlags) && !ctx.rules.enabled(featureDynamicMPT)) - return temDISABLED; + return false; - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; + return true; +} +std::uint32_t +MPTokenIssuanceCreate::getFlagsMask(PreflightContext const& ctx) +{ + // This mask is only compared against sfFlags + return tfMPTokenIssuanceCreateMask; +} + +NotTEC +MPTokenIssuanceCreate::preflight(PreflightContext const& ctx) +{ + // If the mutable flags field is included, at least one flag must be + // specified. if (auto const mutableFlags = ctx.tx[~sfMutableFlags]; mutableFlags && (!*mutableFlags || *mutableFlags & tmfMPTokenIssuanceCreateMutableMask)) return temINVALID_FLAG; - if (ctx.tx.getFlags() & tfMPTokenIssuanceCreateMask) - return temINVALID_FLAG; - if (auto const fee = ctx.tx[~sfTransferFee]) { if (fee > maxTransferFee) @@ -87,7 +93,7 @@ MPTokenIssuanceCreate::preflight(PreflightContext const& ctx) if (maxAmt > maxMPTokenAmount) return temMALFORMED; } - return preflight2(ctx); + return tesSUCCESS; } Expected diff --git a/src/xrpld/app/tx/detail/MPTokenIssuanceCreate.h b/src/xrpld/app/tx/detail/MPTokenIssuanceCreate.h index 0527b9602f..842ed88641 100644 --- a/src/xrpld/app/tx/detail/MPTokenIssuanceCreate.h +++ b/src/xrpld/app/tx/detail/MPTokenIssuanceCreate.h @@ -50,6 +50,12 @@ public: { } + static bool + checkExtraFeatures(PreflightContext const& ctx); + + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC preflight(PreflightContext const& ctx); diff --git a/src/xrpld/app/tx/detail/MPTokenIssuanceDestroy.cpp b/src/xrpld/app/tx/detail/MPTokenIssuanceDestroy.cpp index 2c330ba8f7..4c502f1106 100644 --- a/src/xrpld/app/tx/detail/MPTokenIssuanceDestroy.cpp +++ b/src/xrpld/app/tx/detail/MPTokenIssuanceDestroy.cpp @@ -25,20 +25,16 @@ namespace ripple { +std::uint32_t +MPTokenIssuanceDestroy::getFlagsMask(PreflightContext const& ctx) +{ + return tfMPTokenIssuanceDestroyMask; +} + NotTEC MPTokenIssuanceDestroy::preflight(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureMPTokensV1)) - return temDISABLED; - - // check flags - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfMPTokenIssuanceDestroyMask) - return temINVALID_FLAG; - - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/MPTokenIssuanceDestroy.h b/src/xrpld/app/tx/detail/MPTokenIssuanceDestroy.h index 69abb99feb..2cebdb7352 100644 --- a/src/xrpld/app/tx/detail/MPTokenIssuanceDestroy.h +++ b/src/xrpld/app/tx/detail/MPTokenIssuanceDestroy.h @@ -33,6 +33,9 @@ public: { } + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC preflight(PreflightContext const& ctx); diff --git a/src/xrpld/app/tx/detail/MPTokenIssuanceSet.cpp b/src/xrpld/app/tx/detail/MPTokenIssuanceSet.cpp index 37c563460a..c406a8ec5f 100644 --- a/src/xrpld/app/tx/detail/MPTokenIssuanceSet.cpp +++ b/src/xrpld/app/tx/detail/MPTokenIssuanceSet.cpp @@ -26,6 +26,20 @@ namespace ripple { +bool +MPTokenIssuanceSet::checkExtraFeatures(PreflightContext const& ctx) +{ + return !ctx.tx.isFieldPresent(sfDomainID) || + (ctx.rules.enabled(featurePermissionedDomains) && + ctx.rules.enabled(featureSingleAssetVault)); +} + +std::uint32_t +MPTokenIssuanceSet::getFlagsMask(PreflightContext const& ctx) +{ + return tfMPTokenIssuanceSetMask; +} + // Maps set/clear mutable flags in an MPTokenIssuanceSet transaction to the // corresponding ledger mutable flags that control whether the change is // allowed. @@ -49,14 +63,6 @@ static constexpr std::array mptMutabilityFlags = { NotTEC MPTokenIssuanceSet::preflight(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureMPTokensV1)) - return temDISABLED; - - if (ctx.tx.isFieldPresent(sfDomainID) && - !(ctx.rules.enabled(featurePermissionedDomains) && - ctx.rules.enabled(featureSingleAssetVault))) - return temDISABLED; - auto const mutableFlags = ctx.tx[~sfMutableFlags]; auto const metadata = ctx.tx[~sfMPTokenMetadata]; auto const transferFee = ctx.tx[~sfTransferFee]; @@ -68,16 +74,10 @@ MPTokenIssuanceSet::preflight(PreflightContext const& ctx) if (ctx.tx.isFieldPresent(sfDomainID) && ctx.tx.isFieldPresent(sfHolder)) return temMALFORMED; - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - auto const txFlags = ctx.tx.getFlags(); - // check flags - if (txFlags & tfMPTokenIssuanceSetMask) - return temINVALID_FLAG; // fails if both flags are set - else if ((txFlags & tfMPTLock) && (txFlags & tfMPTUnlock)) + if ((txFlags & tfMPTLock) && (txFlags & tfMPTUnlock)) return temINVALID_FLAG; auto const accountID = ctx.tx[sfAccount]; @@ -133,7 +133,7 @@ MPTokenIssuanceSet::preflight(PreflightContext const& ctx) } } - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/MPTokenIssuanceSet.h b/src/xrpld/app/tx/detail/MPTokenIssuanceSet.h index 5b3db0e75b..f63812097e 100644 --- a/src/xrpld/app/tx/detail/MPTokenIssuanceSet.h +++ b/src/xrpld/app/tx/detail/MPTokenIssuanceSet.h @@ -33,6 +33,12 @@ public: { } + static bool + checkExtraFeatures(PreflightContext const& ctx); + + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC preflight(PreflightContext const& ctx); diff --git a/src/xrpld/app/tx/detail/NFTokenAcceptOffer.cpp b/src/xrpld/app/tx/detail/NFTokenAcceptOffer.cpp index 0cf6a86a37..3b4a27ffd7 100644 --- a/src/xrpld/app/tx/detail/NFTokenAcceptOffer.cpp +++ b/src/xrpld/app/tx/detail/NFTokenAcceptOffer.cpp @@ -27,18 +27,15 @@ namespace ripple { +std::uint32_t +NFTokenAcceptOffer::getFlagsMask(PreflightContext const& ctx) +{ + return tfNFTokenAcceptOfferMask; +} + NotTEC NFTokenAcceptOffer::preflight(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureNonFungibleTokensV1)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfNFTokenAcceptOfferMask) - return temINVALID_FLAG; - auto const bo = ctx.tx[~sfNFTokenBuyOffer]; auto const so = ctx.tx[~sfNFTokenSellOffer]; @@ -57,7 +54,7 @@ NFTokenAcceptOffer::preflight(PreflightContext const& ctx) return temMALFORMED; } - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/NFTokenAcceptOffer.h b/src/xrpld/app/tx/detail/NFTokenAcceptOffer.h index dff3febbb2..995581d1ff 100644 --- a/src/xrpld/app/tx/detail/NFTokenAcceptOffer.h +++ b/src/xrpld/app/tx/detail/NFTokenAcceptOffer.h @@ -51,6 +51,9 @@ public: { } + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC preflight(PreflightContext const& ctx); diff --git a/src/xrpld/app/tx/detail/NFTokenBurn.cpp b/src/xrpld/app/tx/detail/NFTokenBurn.cpp index 947a663f92..cb1b564402 100644 --- a/src/xrpld/app/tx/detail/NFTokenBurn.cpp +++ b/src/xrpld/app/tx/detail/NFTokenBurn.cpp @@ -29,16 +29,7 @@ namespace ripple { NotTEC NFTokenBurn::preflight(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureNonFungibleTokensV1)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; - - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/NFTokenCancelOffer.cpp b/src/xrpld/app/tx/detail/NFTokenCancelOffer.cpp index 3d0bf04a1b..86e804b1a5 100644 --- a/src/xrpld/app/tx/detail/NFTokenCancelOffer.cpp +++ b/src/xrpld/app/tx/detail/NFTokenCancelOffer.cpp @@ -28,18 +28,15 @@ namespace ripple { +std::uint32_t +NFTokenCancelOffer::getFlagsMask(PreflightContext const& ctx) +{ + return tfNFTokenCancelOfferMask; +} + NotTEC NFTokenCancelOffer::preflight(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureNonFungibleTokensV1)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfNFTokenCancelOfferMask) - return temINVALID_FLAG; - if (auto const& ids = ctx.tx[sfNFTokenOffers]; ids.empty() || (ids.size() > maxTokenOfferCancelCount)) return temMALFORMED; @@ -51,7 +48,7 @@ NFTokenCancelOffer::preflight(PreflightContext const& ctx) if (std::adjacent_find(ids.begin(), ids.end()) != ids.end()) return temMALFORMED; - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/NFTokenCancelOffer.h b/src/xrpld/app/tx/detail/NFTokenCancelOffer.h index d460675711..b35be0e757 100644 --- a/src/xrpld/app/tx/detail/NFTokenCancelOffer.h +++ b/src/xrpld/app/tx/detail/NFTokenCancelOffer.h @@ -33,6 +33,9 @@ public: { } + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC preflight(PreflightContext const& ctx); diff --git a/src/xrpld/app/tx/detail/NFTokenCreateOffer.cpp b/src/xrpld/app/tx/detail/NFTokenCreateOffer.cpp index f9cc8c1fc8..2a02fed797 100644 --- a/src/xrpld/app/tx/detail/NFTokenCreateOffer.cpp +++ b/src/xrpld/app/tx/detail/NFTokenCreateOffer.cpp @@ -26,20 +26,17 @@ namespace ripple { +std::uint32_t +NFTokenCreateOffer::getFlagsMask(PreflightContext const& ctx) +{ + return tfNFTokenCreateOfferMask; +} + NotTEC NFTokenCreateOffer::preflight(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureNonFungibleTokensV1)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - auto const txFlags = ctx.tx.getFlags(); - if (txFlags & tfNFTokenCreateOfferMask) - return temINVALID_FLAG; - auto const nftFlags = nft::getFlags(ctx.tx[sfNFTokenID]); // Use implementation shared with NFTokenMint @@ -55,7 +52,7 @@ NFTokenCreateOffer::preflight(PreflightContext const& ctx) !isTesSuccess(notTec)) return notTec; - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/NFTokenCreateOffer.h b/src/xrpld/app/tx/detail/NFTokenCreateOffer.h index 075a5a712f..0a1c631298 100644 --- a/src/xrpld/app/tx/detail/NFTokenCreateOffer.h +++ b/src/xrpld/app/tx/detail/NFTokenCreateOffer.h @@ -33,6 +33,9 @@ public: { } + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC preflight(PreflightContext const& ctx); diff --git a/src/xrpld/app/tx/detail/NFTokenMint.cpp b/src/xrpld/app/tx/detail/NFTokenMint.cpp index 4c07a6e499..8149d3b59d 100644 --- a/src/xrpld/app/tx/detail/NFTokenMint.cpp +++ b/src/xrpld/app/tx/detail/NFTokenMint.cpp @@ -38,22 +38,23 @@ extractNFTokenFlagsFromTxFlags(std::uint32_t txFlags) return static_cast(txFlags & 0x0000FFFF); } -NotTEC -NFTokenMint::preflight(PreflightContext const& ctx) +static bool +hasOfferFields(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureNonFungibleTokensV1)) - return temDISABLED; - - bool const hasOfferFields = ctx.tx.isFieldPresent(sfAmount) || + return ctx.tx.isFieldPresent(sfAmount) || ctx.tx.isFieldPresent(sfDestination) || ctx.tx.isFieldPresent(sfExpiration); +} - if (!ctx.rules.enabled(featureNFTokenMintOffer) && hasOfferFields) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; +bool +NFTokenMint::checkExtraFeatures(PreflightContext const& ctx) +{ + return ctx.rules.enabled(featureNFTokenMintOffer) || !hasOfferFields(ctx); +} +std::uint32_t +NFTokenMint::getFlagsMask(PreflightContext const& ctx) +{ // Prior to fixRemoveNFTokenAutoTrustLine, transfer of an NFToken between // accounts allowed a TrustLine to be added to the issuer of that token // without explicit permission from that issuer. This was enabled by @@ -67,7 +68,7 @@ NFTokenMint::preflight(PreflightContext const& ctx) // The fixRemoveNFTokenAutoTrustLine amendment disables minting with the // tfTrustLine flag as a way to prevent the attack. But until the // amendment passes we still need to keep the old behavior available. - std::uint32_t const NFTokenMintMask = + std::uint32_t const nfTokenMintMask = ctx.rules.enabled(fixRemoveNFTokenAutoTrustLine) // if featureDynamicNFT enabled then new flag allowing mutable URI // available @@ -76,9 +77,12 @@ NFTokenMint::preflight(PreflightContext const& ctx) : ctx.rules.enabled(featureDynamicNFT) ? tfNFTokenMintOldMaskWithMutable : tfNFTokenMintOldMask; - if (ctx.tx.getFlags() & NFTokenMintMask) - return temINVALID_FLAG; + return nfTokenMintMask; +} +NotTEC +NFTokenMint::preflight(PreflightContext const& ctx) +{ if (auto const f = ctx.tx[~sfTransferFee]) { if (f > maxTransferFee) @@ -100,7 +104,7 @@ NFTokenMint::preflight(PreflightContext const& ctx) return temMALFORMED; } - if (hasOfferFields) + if (hasOfferFields(ctx)) { // The Amount field must be present if either the Destination or // Expiration fields are present. @@ -123,7 +127,7 @@ NFTokenMint::preflight(PreflightContext const& ctx) } } - return preflight2(ctx); + return tesSUCCESS; } uint256 diff --git a/src/xrpld/app/tx/detail/NFTokenMint.h b/src/xrpld/app/tx/detail/NFTokenMint.h index f606120c54..1606514559 100644 --- a/src/xrpld/app/tx/detail/NFTokenMint.h +++ b/src/xrpld/app/tx/detail/NFTokenMint.h @@ -36,6 +36,12 @@ public: { } + static bool + checkExtraFeatures(PreflightContext const& ctx); + + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC preflight(PreflightContext const& ctx); diff --git a/src/xrpld/app/tx/detail/NFTokenModify.cpp b/src/xrpld/app/tx/detail/NFTokenModify.cpp index a3803c423b..6ae095411b 100644 --- a/src/xrpld/app/tx/detail/NFTokenModify.cpp +++ b/src/xrpld/app/tx/detail/NFTokenModify.cpp @@ -25,19 +25,15 @@ namespace ripple { +bool +NFTokenModify::checkExtraFeatures(PreflightContext const& ctx) +{ + return ctx.rules.enabled(featureNonFungibleTokensV1_1); +} + NotTEC NFTokenModify::preflight(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureNonFungibleTokensV1_1) || - !ctx.rules.enabled(featureDynamicNFT)) - return temDISABLED; - - if (NotTEC const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; - if (auto owner = ctx.tx[~sfOwner]; owner == ctx.tx[sfAccount]) return temMALFORMED; @@ -47,7 +43,7 @@ NFTokenModify::preflight(PreflightContext const& ctx) return temMALFORMED; } - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/NFTokenModify.h b/src/xrpld/app/tx/detail/NFTokenModify.h index 0d1e72ade1..04784381fb 100644 --- a/src/xrpld/app/tx/detail/NFTokenModify.h +++ b/src/xrpld/app/tx/detail/NFTokenModify.h @@ -33,6 +33,9 @@ public: { } + static bool + checkExtraFeatures(PreflightContext const& ctx); + static NotTEC preflight(PreflightContext const& ctx); diff --git a/src/xrpld/app/tx/detail/PayChan.cpp b/src/xrpld/app/tx/detail/PayChan.cpp index bdfe0d5c95..32c0abeb93 100644 --- a/src/xrpld/app/tx/detail/PayChan.cpp +++ b/src/xrpld/app/tx/detail/PayChan.cpp @@ -171,15 +171,16 @@ PayChanCreate::makeTxConsequences(PreflightContext const& ctx) return TxConsequences{ctx.tx, ctx.tx[sfAmount].xrp()}; } +std::uint32_t +PayChanCreate::getFlagsMask(PreflightContext const& ctx) +{ + // 0 means "Allow any flags" + return ctx.rules.enabled(fix1543) ? tfUniversalMask : 0; +} + NotTEC PayChanCreate::preflight(PreflightContext const& ctx) { - if (ctx.rules.enabled(fix1543) && ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - if (!isXRP(ctx.tx[sfAmount]) || (ctx.tx[sfAmount] <= beast::zero)) return temBAD_AMOUNT; @@ -189,7 +190,7 @@ PayChanCreate::preflight(PreflightContext const& ctx) if (!publicKeyType(ctx.tx[sfPublicKey])) return temMALFORMED; - return preflight2(ctx); + return tesSUCCESS; } TER @@ -330,19 +331,20 @@ PayChanFund::makeTxConsequences(PreflightContext const& ctx) return TxConsequences{ctx.tx, ctx.tx[sfAmount].xrp()}; } +std::uint32_t +PayChanFund::getFlagsMask(PreflightContext const& ctx) +{ + // 0 means "Allow any flags" + return ctx.rules.enabled(fix1543) ? tfUniversalMask : 0; +} + NotTEC PayChanFund::preflight(PreflightContext const& ctx) { - if (ctx.rules.enabled(fix1543) && ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - if (!isXRP(ctx.tx[sfAmount]) || (ctx.tx[sfAmount] <= beast::zero)) return temBAD_AMOUNT; - return preflight2(ctx); + return tesSUCCESS; } TER @@ -420,16 +422,23 @@ PayChanFund::doApply() //------------------------------------------------------------------------------ +bool +PayChanClaim::checkExtraFeatures(PreflightContext const& ctx) +{ + return !ctx.tx.isFieldPresent(sfCredentialIDs) || + ctx.rules.enabled(featureCredentials); +} + +std::uint32_t +PayChanClaim::getFlagsMask(PreflightContext const& ctx) +{ + // 0 means "Allow any flags" + return ctx.rules.enabled(fix1543) ? tfPayChanClaimMask : 0; +} + NotTEC PayChanClaim::preflight(PreflightContext const& ctx) { - if (ctx.tx.isFieldPresent(sfCredentialIDs) && - !ctx.rules.enabled(featureCredentials)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - auto const bal = ctx.tx[~sfBalance]; if (bal && (!isXRP(*bal) || *bal <= beast::zero)) return temBAD_AMOUNT; @@ -444,9 +453,6 @@ PayChanClaim::preflight(PreflightContext const& ctx) { auto const flags = ctx.tx.getFlags(); - if (ctx.rules.enabled(fix1543) && (flags & tfPayChanClaimMask)) - return temINVALID_FLAG; - if ((flags & tfClose) && (flags & tfRenew)) return temMALFORMED; } @@ -481,7 +487,7 @@ PayChanClaim::preflight(PreflightContext const& ctx) !isTesSuccess(err)) return err; - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/PayChan.h b/src/xrpld/app/tx/detail/PayChan.h index 2e09c473dc..b25a4529be 100644 --- a/src/xrpld/app/tx/detail/PayChan.h +++ b/src/xrpld/app/tx/detail/PayChan.h @@ -36,6 +36,9 @@ public: static TxConsequences makeTxConsequences(PreflightContext const& ctx); + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC preflight(PreflightContext const& ctx); @@ -62,6 +65,9 @@ public: static TxConsequences makeTxConsequences(PreflightContext const& ctx); + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC preflight(PreflightContext const& ctx); @@ -82,6 +88,12 @@ public: { } + static bool + checkExtraFeatures(PreflightContext const& ctx); + + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC preflight(PreflightContext const& ctx); diff --git a/src/xrpld/app/tx/detail/Payment.cpp b/src/xrpld/app/tx/detail/Payment.cpp index e622d54498..8bc0e891d0 100644 --- a/src/xrpld/app/tx/detail/Payment.cpp +++ b/src/xrpld/app/tx/detail/Payment.cpp @@ -65,20 +65,33 @@ getMaxSourceAmount( dstAmount < beast::zero); } -NotTEC -Payment::preflight(PreflightContext const& ctx) +bool +Payment::checkExtraFeatures(PreflightContext const& ctx) { if (ctx.tx.isFieldPresent(sfCredentialIDs) && !ctx.rules.enabled(featureCredentials)) - return temDISABLED; - + return false; if (ctx.tx.isFieldPresent(sfDomainID) && !ctx.rules.enabled(featurePermissionedDEX)) - return temDISABLED; + return false; - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; + return true; +} +std::uint32_t +Payment::getFlagsMask(PreflightContext const& ctx) +{ + auto& tx = ctx.tx; + + STAmount const dstAmount(tx.getFieldAmount(sfAmount)); + bool const mptDirect = dstAmount.holds(); + + return mptDirect ? tfMPTPaymentMask : tfPaymentMask; +} + +NotTEC +Payment::preflight(PreflightContext const& ctx) +{ auto& tx = ctx.tx; auto& j = ctx.j; @@ -90,14 +103,6 @@ Payment::preflight(PreflightContext const& ctx) std::uint32_t const txFlags = tx.getFlags(); - std::uint32_t paymentMask = mptDirect ? tfMPTPaymentMask : tfPaymentMask; - - if (txFlags & paymentMask) - { - JLOG(j.trace()) << "Malformed transaction: Invalid flags set."; - return temINVALID_FLAG; - } - if (mptDirect && ctx.tx.isFieldPresent(sfPaths)) return temMALFORMED; @@ -242,7 +247,7 @@ Payment::preflight(PreflightContext const& ctx) !isTesSuccess(err)) return err; - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/Payment.h b/src/xrpld/app/tx/detail/Payment.h index 010a2453cf..04bba390e2 100644 --- a/src/xrpld/app/tx/detail/Payment.h +++ b/src/xrpld/app/tx/detail/Payment.h @@ -42,6 +42,12 @@ public: static TxConsequences makeTxConsequences(PreflightContext const& ctx); + static bool + checkExtraFeatures(PreflightContext const& ctx); + + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC preflight(PreflightContext const& ctx); diff --git a/src/xrpld/app/tx/detail/PermissionedDomainDelete.cpp b/src/xrpld/app/tx/detail/PermissionedDomainDelete.cpp index 76224ba6b3..9fe48ba515 100644 --- a/src/xrpld/app/tx/detail/PermissionedDomainDelete.cpp +++ b/src/xrpld/app/tx/detail/PermissionedDomainDelete.cpp @@ -27,23 +27,11 @@ namespace ripple { NotTEC PermissionedDomainDelete::preflight(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featurePermissionedDomains)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfUniversalMask) - { - JLOG(ctx.j.debug()) << "PermissionedDomainDelete: invalid flags."; - return temINVALID_FLAG; - } - auto const domain = ctx.tx.getFieldH256(sfDomainID); if (domain == beast::zero) return temMALFORMED; - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/PermissionedDomainSet.cpp b/src/xrpld/app/tx/detail/PermissionedDomainSet.cpp index cc25809aa1..d9fa481bb6 100644 --- a/src/xrpld/app/tx/detail/PermissionedDomainSet.cpp +++ b/src/xrpld/app/tx/detail/PermissionedDomainSet.cpp @@ -28,22 +28,15 @@ namespace ripple { +bool +PermissionedDomainSet::checkExtraFeatures(PreflightContext const& ctx) +{ + return ctx.rules.enabled(featureCredentials); +} + NotTEC PermissionedDomainSet::preflight(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featurePermissionedDomains) || - !ctx.rules.enabled(featureCredentials)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfUniversalMask) - { - JLOG(ctx.j.debug()) << "PermissionedDomainSet: invalid flags."; - return temINVALID_FLAG; - } - if (auto err = credentials::checkArray( ctx.tx.getFieldArray(sfAcceptedCredentials), maxPermissionedDomainCredentialsArraySize, @@ -55,7 +48,7 @@ PermissionedDomainSet::preflight(PreflightContext const& ctx) if (domain && *domain == beast::zero) return temMALFORMED; - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/PermissionedDomainSet.h b/src/xrpld/app/tx/detail/PermissionedDomainSet.h index 502d576e32..ed27896a3b 100644 --- a/src/xrpld/app/tx/detail/PermissionedDomainSet.h +++ b/src/xrpld/app/tx/detail/PermissionedDomainSet.h @@ -33,6 +33,9 @@ public: { } + static bool + checkExtraFeatures(PreflightContext const& ctx); + static NotTEC preflight(PreflightContext const& ctx); diff --git a/src/xrpld/app/tx/detail/SetAccount.cpp b/src/xrpld/app/tx/detail/SetAccount.cpp index dc84c7cc7e..c2129ba1e1 100644 --- a/src/xrpld/app/tx/detail/SetAccount.cpp +++ b/src/xrpld/app/tx/detail/SetAccount.cpp @@ -57,23 +57,20 @@ SetAccount::makeTxConsequences(PreflightContext const& ctx) return TxConsequences{ctx.tx, getTxConsequencesCategory(ctx.tx)}; } +std::uint32_t +SetAccount::getFlagsMask(PreflightContext const& ctx) +{ + return tfAccountSetMask; +} + NotTEC SetAccount::preflight(PreflightContext const& ctx) { - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - auto& tx = ctx.tx; auto& j = ctx.j; std::uint32_t const uTxFlags = tx.getFlags(); - if (uTxFlags & tfAccountSetMask) - { - JLOG(j.trace()) << "Malformed transaction: Invalid flags set."; - return temINVALID_FLAG; - } - std::uint32_t const uSetFlag = tx.getFieldU32(sfSetFlag); std::uint32_t const uClearFlag = tx.getFieldU32(sfClearFlag); @@ -186,7 +183,7 @@ SetAccount::preflight(PreflightContext const& ctx) return temMALFORMED; } - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/SetAccount.h b/src/xrpld/app/tx/detail/SetAccount.h index ed4242c250..bcc0a61b1b 100644 --- a/src/xrpld/app/tx/detail/SetAccount.h +++ b/src/xrpld/app/tx/detail/SetAccount.h @@ -38,6 +38,9 @@ public: static TxConsequences makeTxConsequences(PreflightContext const& ctx); + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC preflight(PreflightContext const& ctx); diff --git a/src/xrpld/app/tx/detail/SetOracle.cpp b/src/xrpld/app/tx/detail/SetOracle.cpp index 78ff8e2953..81f20b4342 100644 --- a/src/xrpld/app/tx/detail/SetOracle.cpp +++ b/src/xrpld/app/tx/detail/SetOracle.cpp @@ -39,15 +39,6 @@ tokenPairKey(STObject const& pair) NotTEC SetOracle::preflight(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featurePriceOracle)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; - auto const& dataSeries = ctx.tx.getFieldArray(sfPriceDataSeries); if (dataSeries.empty()) return temARRAY_EMPTY; @@ -64,7 +55,7 @@ SetOracle::preflight(PreflightContext const& ctx) isInvalidLength(sfAssetClass, maxOracleSymbolClass)) return temMALFORMED; - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/SetRegularKey.cpp b/src/xrpld/app/tx/detail/SetRegularKey.cpp index 92d130a15a..4e063e7d1f 100644 --- a/src/xrpld/app/tx/detail/SetRegularKey.cpp +++ b/src/xrpld/app/tx/detail/SetRegularKey.cpp @@ -51,18 +51,6 @@ SetRegularKey::calculateBaseFee(ReadView const& view, STTx const& tx) NotTEC SetRegularKey::preflight(PreflightContext const& ctx) { - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - std::uint32_t const uTxFlags = ctx.tx.getFlags(); - - if (uTxFlags & tfUniversalMask) - { - JLOG(ctx.j.trace()) << "Malformed transaction: Invalid flags set."; - - return temINVALID_FLAG; - } - if (ctx.rules.enabled(fixMasterKeyAsRegularKey) && ctx.tx.isFieldPresent(sfRegularKey) && (ctx.tx.getAccountID(sfRegularKey) == ctx.tx.getAccountID(sfAccount))) @@ -70,7 +58,7 @@ SetRegularKey::preflight(PreflightContext const& ctx) return temBAD_REGKEY; } - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/SetSignerList.cpp b/src/xrpld/app/tx/detail/SetSignerList.cpp index 60f92cf87b..b5d9d4d5b8 100644 --- a/src/xrpld/app/tx/detail/SetSignerList.cpp +++ b/src/xrpld/app/tx/detail/SetSignerList.cpp @@ -77,19 +77,16 @@ SetSignerList::determineOperation( return std::make_tuple(tesSUCCESS, quorum, sign, op); } +std::uint32_t +SetSignerList::getFlagsMask(PreflightContext const& ctx) +{ + // 0 means "Allow any flags" + return ctx.rules.enabled(fixInvalidTxFlags) ? tfUniversalMask : 0; +} + NotTEC SetSignerList::preflight(PreflightContext const& ctx) { - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.rules.enabled(fixInvalidTxFlags) && - (ctx.tx.getFlags() & tfUniversalMask)) - { - JLOG(ctx.j.debug()) << "SetSignerList: invalid flags."; - return temINVALID_FLAG; - } - auto const result = determineOperation(ctx.tx, ctx.flags, ctx.j); if (std::get<0>(result) != tesSUCCESS) @@ -119,7 +116,7 @@ SetSignerList::preflight(PreflightContext const& ctx) } } - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/SetSignerList.h b/src/xrpld/app/tx/detail/SetSignerList.h index 1827aca975..be2df8152e 100644 --- a/src/xrpld/app/tx/detail/SetSignerList.h +++ b/src/xrpld/app/tx/detail/SetSignerList.h @@ -51,6 +51,9 @@ public: { } + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC preflight(PreflightContext const& ctx); diff --git a/src/xrpld/app/tx/detail/SetTrust.cpp b/src/xrpld/app/tx/detail/SetTrust.cpp index 87f1721b29..21d4534f93 100644 --- a/src/xrpld/app/tx/detail/SetTrust.cpp +++ b/src/xrpld/app/tx/detail/SetTrust.cpp @@ -67,23 +67,20 @@ computeFreezeFlags( namespace ripple { +std::uint32_t +SetTrust::getFlagsMask(PreflightContext const& ctx) +{ + return tfTrustSetMask; +} + NotTEC SetTrust::preflight(PreflightContext const& ctx) { - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - auto& tx = ctx.tx; auto& j = ctx.j; std::uint32_t const uTxFlags = tx.getFlags(); - if (uTxFlags & tfTrustSetMask) - { - JLOG(j.trace()) << "Malformed transaction: Invalid flags set."; - return temINVALID_FLAG; - } - if (!ctx.rules.enabled(featureDeepFreeze)) { // Even though the deep freeze flags are included in the @@ -127,7 +124,7 @@ SetTrust::preflight(PreflightContext const& ctx) return temDST_NEEDED; } - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/SetTrust.h b/src/xrpld/app/tx/detail/SetTrust.h index a0476918ac..443080bf74 100644 --- a/src/xrpld/app/tx/detail/SetTrust.h +++ b/src/xrpld/app/tx/detail/SetTrust.h @@ -35,6 +35,9 @@ public: { } + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC preflight(PreflightContext const& ctx); diff --git a/src/xrpld/app/tx/detail/Transactor.cpp b/src/xrpld/app/tx/detail/Transactor.cpp index fd396e4556..1c98233964 100644 --- a/src/xrpld/app/tx/detail/Transactor.cpp +++ b/src/xrpld/app/tx/detail/Transactor.cpp @@ -41,7 +41,7 @@ namespace ripple { /** Performs early sanity checks on the txid */ NotTEC -preflight0(PreflightContext const& ctx) +preflight0(PreflightContext const& ctx, std::uint32_t flagMask) { if (isPseudoTx(ctx.tx) && ctx.tx.isFlag(tfInnerBatchTxn)) { @@ -83,12 +83,84 @@ preflight0(PreflightContext const& ctx) return temINVALID; } + if (ctx.tx.getFlags() & flagMask) + { + JLOG(ctx.j.debug()) + << ctx.tx.peekAtField(sfTransactionType).getFullText() + << ": invalid flags."; + return temINVALID_FLAG; + } + return tesSUCCESS; } +namespace detail { + +/** Checks the validity of the transactor signing key. + * + * Normally called from preflight1. + */ +NotTEC +preflightCheckSigningKey(STObject const& sigObject, beast::Journal j) +{ + if (auto const spk = sigObject.getFieldVL(sfSigningPubKey); + !spk.empty() && !publicKeyType(makeSlice(spk))) + { + JLOG(j.debug()) << "preflightCheckSigningKey: invalid signing key"; + return temBAD_SIGNATURE; + } + return tesSUCCESS; +} + +std::optional +preflightCheckSimulateKeys( + ApplyFlags flags, + STObject const& sigObject, + beast::Journal j) +{ + if (flags & tapDRY_RUN) // simulation + { + std::optional const signature = sigObject[~sfTxnSignature]; + if (signature && !signature->empty()) + { + // NOTE: This code should never be hit because it's checked in the + // `simulate` RPC + return temINVALID; // LCOV_EXCL_LINE + } + + if (!sigObject.isFieldPresent(sfSigners)) + { + // no signers, no signature - a valid simulation + return tesSUCCESS; + } + + for (auto const& signer : sigObject.getFieldArray(sfSigners)) + { + if (signer.isFieldPresent(sfTxnSignature) && + !signer[sfTxnSignature].empty()) + { + // NOTE: This code should never be hit because it's + // checked in the `simulate` RPC + return temINVALID; // LCOV_EXCL_LINE + } + } + + Slice const signingPubKey = sigObject[sfSigningPubKey]; + if (!signingPubKey.empty()) + { + // trying to single-sign _and_ multi-sign a transaction + return temINVALID; + } + return tesSUCCESS; + } + return {}; +} + +} // namespace detail + /** Performs early sanity checks on the account and fee fields */ NotTEC -preflight1(PreflightContext const& ctx) +Transactor::preflight1(PreflightContext const& ctx, std::uint32_t flagMask) { // This is inappropriate in preflight0, because only Change transactions // skip this function, and those do not allow an sfTicketSequence field. @@ -107,8 +179,7 @@ preflight1(PreflightContext const& ctx) return temBAD_SIGNER; } - auto const ret = preflight0(ctx); - if (!isTesSuccess(ret)) + if (auto const ret = preflight0(ctx, flagMask)) return ret; auto const id = ctx.tx.getAccountID(sfAccount); @@ -126,13 +197,8 @@ preflight1(PreflightContext const& ctx) return temBAD_FEE; } - auto const spk = ctx.tx.getSigningPubKey(); - - if (!spk.empty() && !publicKeyType(makeSlice(spk))) - { - JLOG(ctx.j.debug()) << "preflight1: invalid signing key"; - return temBAD_SIGNATURE; - } + if (auto const ret = detail::preflightCheckSigningKey(ctx.tx, ctx.j)) + return ret; // An AccountTxnID field constrains transaction ordering more than the // Sequence field. Tickets, on the other hand, reduce ordering @@ -157,41 +223,13 @@ preflight1(PreflightContext const& ctx) /** Checks whether the signature appears valid */ NotTEC -preflight2(PreflightContext const& ctx) +Transactor::preflight2(PreflightContext const& ctx) { - if (ctx.flags & tapDRY_RUN) // simulation - { - if (!ctx.tx.getSignature().empty()) - { - // NOTE: This code should never be hit because it's checked in the - // `simulate` RPC - return temINVALID; // LCOV_EXCL_LINE - } - - if (!ctx.tx.isFieldPresent(sfSigners)) - { - // no signers, no signature - a valid simulation - return tesSUCCESS; - } - - for (auto const& signer : ctx.tx.getFieldArray(sfSigners)) - { - if (signer.isFieldPresent(sfTxnSignature) && - !signer[sfTxnSignature].empty()) - { - // NOTE: This code should never be hit because it's - // checked in the `simulate` RPC - return temINVALID; // LCOV_EXCL_LINE - } - } - - if (!ctx.tx.getSigningPubKey().empty()) - { - // trying to single-sign _and_ multi-sign a transaction - return temINVALID; - } - return tesSUCCESS; - } + if (auto const ret = + detail::preflightCheckSimulateKeys(ctx.flags, ctx.tx, ctx.j)) + // Skips following checks if the transaction is being simulated, + // regardless of success or failure + return *ret; auto const sigValid = checkValidity( ctx.app.getHashRouter(), ctx.tx, ctx.rules, ctx.app.config()); @@ -213,6 +251,28 @@ Transactor::Transactor(ApplyContext& ctx) { } +bool +Transactor::validDataLength( + std::optional const& slice, + std::size_t maxLength) +{ + if (!slice) + return true; + return !slice->empty() && slice->length() <= maxLength; +} + +std::uint32_t +Transactor::getFlagsMask(PreflightContext const& ctx) +{ + return tfUniversalMask; +} + +NotTEC +Transactor::preflightSigValidated(PreflightContext const& ctx) +{ + return tesSUCCESS; +} + TER Transactor::checkPermission(ReadView const& view, STTx const& tx) { @@ -247,6 +307,27 @@ Transactor::calculateBaseFee(ReadView const& view, STTx const& tx) return baseFee + (signerCount * baseFee); } +// Returns the fee in fee units, not scaled for load. +XRPAmount +Transactor::calculateOwnerReserveFee(ReadView const& view, STTx const& tx) +{ + // Assumption: One reserve increment is typically much greater than one base + // fee. + // This check is in an assert so that it will come to the attention of + // developers if that assumption is not correct. If the owner reserve is not + // significantly larger than the base fee (or even worse, smaller), we will + // need to rethink charging an owner reserve as a transaction fee. + // TODO: This function is static, and I don't want to add more parameters. + // When it is finally refactored to be in a context that has access to the + // Application, include "app().overlay().networkID() > 2 ||" in the + // condition. + XRPL_ASSERT( + view.fees().increment > view.fees().base * 100, + "ripple::Transactor::calculateOwnerReserveFee : Owner reserve is " + "reasonable"); + return view.fees().increment; +} + XRPAmount Transactor::minimumFee( Application& app, diff --git a/src/xrpld/app/tx/detail/Transactor.h b/src/xrpld/app/tx/detail/Transactor.h index e94b93523d..88b0664ea2 100644 --- a/src/xrpld/app/tx/detail/Transactor.h +++ b/src/xrpld/app/tx/detail/Transactor.h @@ -134,6 +134,8 @@ public: class TxConsequences; struct PreflightResult; +// Needed for preflight specialization +class Change; class Transactor { @@ -198,6 +200,35 @@ public: static XRPAmount calculateBaseFee(ReadView const& view, STTx const& tx); + /* Do NOT define an invokePreflight function in a derived class. + Instead, define: + + // Optional if the transaction is gated on an amendment that + // isn't specified in transactions.macro + static bool + checkExtraFeatures(PreflightContext const& ctx); + + // Optional if the transaction uses any flags other than tfUniversal + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + + // Required, even if it just returns tesSUCCESS. + static NotTEC + preflight(PreflightContext const& ctx); + + // Optional, rarely needed, if the transaction does any expensive + // checks after the signature is verified. + static NotTEC preflightSigValidated(PreflightContext const& ctx); + + * Do not try to call preflight1 or preflight2 directly. + * Do not check whether relevant amendments are enabled in preflight. + Instead, define checkExtraFeatures. + * Do not check flags in preflight. Instead, define getFlagsMask. + */ + template + static NotTEC + invokePreflight(PreflightContext const& ctx); + static TER preclaim(PreclaimContext const& ctx) { @@ -246,6 +277,36 @@ protected: Fees const& fees, ApplyFlags flags); + // Returns the fee in fee units, not scaled for load. + static XRPAmount + calculateOwnerReserveFee(ReadView const& view, STTx const& tx); + + // Base class always returns true + static bool + checkExtraFeatures(PreflightContext const& ctx); + + // Base class always returns tfUniversalMask + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + + // Base class always returns tesSUCCESS + static NotTEC + preflightSigValidated(PreflightContext const& ctx); + + static bool + validDataLength(std::optional const& slice, std::size_t maxLength); + + template + static bool + validNumericRange(std::optional value, T max, T min = {}); + + template + static bool + validNumericRange( + std::optional value, + unit::ValueUnit max, + unit::ValueUnit min = {}); + private: std::pair reset(XRPAmount fee); @@ -270,19 +331,106 @@ private: beast::Journal j); void trapTransaction(uint256) const; + + /** Performs early sanity checks on the account and fee fields. + + (And passes flagMask to preflight0) + + Do not try to call preflight1 from preflight() in derived classes. See + the description of invokePreflight for details. + */ + static NotTEC + preflight1(PreflightContext const& ctx, std::uint32_t flagMask); + + /** Checks whether the signature appears valid + + Do not try to call preflight2 from preflight() in derived classes. See + the description of invokePreflight for details. + */ + static NotTEC + preflight2(PreflightContext const& ctx); }; -/** Performs early sanity checks on the txid */ -NotTEC -preflight0(PreflightContext const& ctx); +inline bool +Transactor::checkExtraFeatures(PreflightContext const& ctx) +{ + return true; +} -/** Performs early sanity checks on the account and fee fields */ +/** Performs early sanity checks on the txid and flags */ NotTEC -preflight1(PreflightContext const& ctx); +preflight0(PreflightContext const& ctx, std::uint32_t flagMask); -/** Checks whether the signature appears valid */ +namespace detail { + +/** Checks the validity of the transactor signing key. + * + * Normally called from preflight1 with ctx.tx. + */ NotTEC -preflight2(PreflightContext const& ctx); +preflightCheckSigningKey(STObject const& sigObject, beast::Journal j); + +/** Checks the special signing key state needed for simulation + * + * Normally called from preflight2 with ctx.tx. + */ +std::optional +preflightCheckSimulateKeys( + ApplyFlags flags, + STObject const& sigObject, + beast::Journal j); +} // namespace detail + +// Defined in Change.cpp +template <> +NotTEC +Transactor::invokePreflight(PreflightContext const& ctx); + +template +NotTEC +Transactor::invokePreflight(PreflightContext const& ctx) +{ + // Using this lookup does NOT require checking the fixDelegateV1_1. The data + // exists regardless of whether it is enabled. + auto const feature = + Permission::getInstance().getTxFeature(ctx.tx.getTxnType()); + + if (feature && !ctx.rules.enabled(*feature)) + return temDISABLED; + + if (!T::checkExtraFeatures(ctx)) + return temDISABLED; + + if (auto const ret = preflight1(ctx, T::getFlagsMask(ctx))) + return ret; + + if (auto const ret = T::preflight(ctx)) + return ret; + + if (auto const ret = preflight2(ctx)) + return ret; + + return T::preflightSigValidated(ctx); +} + +template +bool +Transactor::validNumericRange(std::optional value, T max, T min) +{ + if (!value) + return true; + return value >= min && value <= max; +} + +template +bool +Transactor::validNumericRange( + std::optional value, + unit::ValueUnit max, + unit::ValueUnit min) +{ + return validNumericRange(value, max.value(), min.value()); +} } // namespace ripple diff --git a/src/xrpld/app/tx/detail/VaultClawback.cpp b/src/xrpld/app/tx/detail/VaultClawback.cpp index 061aacdbb8..45a56a6292 100644 --- a/src/xrpld/app/tx/detail/VaultClawback.cpp +++ b/src/xrpld/app/tx/detail/VaultClawback.cpp @@ -35,15 +35,6 @@ namespace ripple { NotTEC VaultClawback::preflight(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureSingleAssetVault)) - return temDISABLED; - - if (auto const ter = preflight1(ctx)) - return ter; - - if (ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; - if (ctx.tx[sfVaultID] == beast::zero) { JLOG(ctx.j.debug()) << "VaultClawback: zero/empty vault ID."; @@ -78,7 +69,7 @@ VaultClawback::preflight(PreflightContext const& ctx) } } - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/VaultCreate.cpp b/src/xrpld/app/tx/detail/VaultCreate.cpp index 855275bf4e..9447976a32 100644 --- a/src/xrpld/app/tx/detail/VaultCreate.cpp +++ b/src/xrpld/app/tx/detail/VaultCreate.cpp @@ -35,28 +35,27 @@ namespace ripple { +bool +VaultCreate::checkExtraFeatures(PreflightContext const& ctx) +{ + if (!ctx.rules.enabled(featureMPTokensV1)) + return false; + + return !ctx.tx.isFieldPresent(sfDomainID) || + ctx.rules.enabled(featurePermissionedDomains); +} + +std::uint32_t +VaultCreate::getFlagsMask(PreflightContext const& ctx) +{ + return tfVaultCreateMask; +} + NotTEC VaultCreate::preflight(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureSingleAssetVault) || - !ctx.rules.enabled(featureMPTokensV1)) - return temDISABLED; - - if (ctx.tx.isFieldPresent(sfDomainID) && - !ctx.rules.enabled(featurePermissionedDomains)) - return temDISABLED; - - if (auto const ter = preflight1(ctx)) - return ter; - - if (ctx.tx.getFlags() & tfVaultCreateMask) - return temINVALID_FLAG; - - if (auto const data = ctx.tx[~sfData]) - { - if (data->empty() || data->length() > maxDataPayloadLength) - return temMALFORMED; - } + if (!validDataLength(ctx.tx[~sfData], maxDataPayloadLength)) + return temMALFORMED; if (auto const withdrawalPolicy = ctx.tx[~sfWithdrawalPolicy]) { @@ -96,14 +95,14 @@ VaultCreate::preflight(PreflightContext const& ctx) return temMALFORMED; } - return preflight2(ctx); + return tesSUCCESS; } XRPAmount VaultCreate::calculateBaseFee(ReadView const& view, STTx const& tx) { // One reserve increment is typically much greater than one base fee. - return view.fees().increment; + return calculateOwnerReserveFee(view, tx); } TER @@ -112,32 +111,8 @@ VaultCreate::preclaim(PreclaimContext const& ctx) auto const vaultAsset = ctx.tx[sfAsset]; auto const account = ctx.tx[sfAccount]; - if (vaultAsset.native()) - ; // No special checks for XRP - else if (vaultAsset.holds()) - { - auto mptID = vaultAsset.get().getMptID(); - auto issuance = ctx.view.read(keylet::mptIssuance(mptID)); - if (!issuance) - return tecOBJECT_NOT_FOUND; - if (!issuance->isFlag(lsfMPTCanTransfer)) - { - // NOTE: flag lsfMPTCanTransfer is immutable, so this is debug in - // VaultCreate only; in other vault function it's an error. - JLOG(ctx.j.debug()) - << "VaultCreate: vault assets are non-transferable."; - return tecNO_AUTH; - } - } - else if (vaultAsset.holds()) - { - auto const issuer = - ctx.view.read(keylet::account(vaultAsset.getIssuer())); - if (!issuer) - return terNO_ACCOUNT; - else if (!issuer->isFlag(lsfDefaultRipple)) - return terNO_RIPPLE; - } + if (auto const ter = canAddHolding(ctx.view, vaultAsset)) + return ter; // Check for pseudo-account issuers - we do not want a vault to hold such // assets (e.g. MPT shares to other vaults or AMM LPTokens) as they would be diff --git a/src/xrpld/app/tx/detail/VaultCreate.h b/src/xrpld/app/tx/detail/VaultCreate.h index 5555644629..3f952d540a 100644 --- a/src/xrpld/app/tx/detail/VaultCreate.h +++ b/src/xrpld/app/tx/detail/VaultCreate.h @@ -33,6 +33,12 @@ public: { } + static bool + checkExtraFeatures(PreflightContext const& ctx); + + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC preflight(PreflightContext const& ctx); diff --git a/src/xrpld/app/tx/detail/VaultDelete.cpp b/src/xrpld/app/tx/detail/VaultDelete.cpp index 5e4e16a99b..ab7db78956 100644 --- a/src/xrpld/app/tx/detail/VaultDelete.cpp +++ b/src/xrpld/app/tx/detail/VaultDelete.cpp @@ -31,22 +31,13 @@ namespace ripple { NotTEC VaultDelete::preflight(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureSingleAssetVault)) - return temDISABLED; - - if (auto const ter = preflight1(ctx)) - return ter; - - if (ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; - if (ctx.tx[sfVaultID] == beast::zero) { JLOG(ctx.j.debug()) << "VaultDelete: zero/empty vault ID."; return temMALFORMED; } - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/VaultDeposit.cpp b/src/xrpld/app/tx/detail/VaultDeposit.cpp index 3d346d63a2..75cf81b0b0 100644 --- a/src/xrpld/app/tx/detail/VaultDeposit.cpp +++ b/src/xrpld/app/tx/detail/VaultDeposit.cpp @@ -36,15 +36,6 @@ namespace ripple { NotTEC VaultDeposit::preflight(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureSingleAssetVault)) - return temDISABLED; - - if (auto const ter = preflight1(ctx)) - return ter; - - if (ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; - if (ctx.tx[sfVaultID] == beast::zero) { JLOG(ctx.j.debug()) << "VaultDeposit: zero/empty vault ID."; @@ -54,7 +45,7 @@ VaultDeposit::preflight(PreflightContext const& ctx) if (ctx.tx[sfAmount] <= beast::zero) return temBAD_AMOUNT; - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/VaultSet.cpp b/src/xrpld/app/tx/detail/VaultSet.cpp index 5a519f81cf..6057e40cfa 100644 --- a/src/xrpld/app/tx/detail/VaultSet.cpp +++ b/src/xrpld/app/tx/detail/VaultSet.cpp @@ -30,28 +30,22 @@ namespace ripple { +bool +VaultSet::checkExtraFeatures(PreflightContext const& ctx) +{ + return !ctx.tx.isFieldPresent(sfDomainID) || + ctx.rules.enabled(featurePermissionedDomains); +} + NotTEC VaultSet::preflight(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureSingleAssetVault)) - return temDISABLED; - - if (ctx.tx.isFieldPresent(sfDomainID) && - !ctx.rules.enabled(featurePermissionedDomains)) - return temDISABLED; - - if (auto const ter = preflight1(ctx)) - return ter; - if (ctx.tx[sfVaultID] == beast::zero) { JLOG(ctx.j.debug()) << "VaultSet: zero/empty vault ID."; return temMALFORMED; } - if (ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; - if (auto const data = ctx.tx[~sfData]) { if (data->empty() || data->length() > maxDataPayloadLength) @@ -78,7 +72,7 @@ VaultSet::preflight(PreflightContext const& ctx) return temMALFORMED; } - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/VaultSet.h b/src/xrpld/app/tx/detail/VaultSet.h index f16aa6c284..b3eecbbab5 100644 --- a/src/xrpld/app/tx/detail/VaultSet.h +++ b/src/xrpld/app/tx/detail/VaultSet.h @@ -33,6 +33,9 @@ public: { } + static bool + checkExtraFeatures(PreflightContext const& ctx); + static NotTEC preflight(PreflightContext const& ctx); diff --git a/src/xrpld/app/tx/detail/VaultWithdraw.cpp b/src/xrpld/app/tx/detail/VaultWithdraw.cpp index 63cc22fe48..509b795058 100644 --- a/src/xrpld/app/tx/detail/VaultWithdraw.cpp +++ b/src/xrpld/app/tx/detail/VaultWithdraw.cpp @@ -33,15 +33,6 @@ namespace ripple { NotTEC VaultWithdraw::preflight(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureSingleAssetVault)) - return temDISABLED; - - if (auto const ter = preflight1(ctx)) - return ter; - - if (ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; - if (ctx.tx[sfVaultID] == beast::zero) { JLOG(ctx.j.debug()) << "VaultWithdraw: zero/empty vault ID."; @@ -68,7 +59,7 @@ VaultWithdraw::preflight(PreflightContext const& ctx) return temMALFORMED; } - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/XChainBridge.cpp b/src/xrpld/app/tx/detail/XChainBridge.cpp index 92e3c7f625..2587845df5 100644 --- a/src/xrpld/app/tx/detail/XChainBridge.cpp +++ b/src/xrpld/app/tx/detail/XChainBridge.cpp @@ -1210,17 +1210,8 @@ toClaim(STTx const& tx) template NotTEC -attestationPreflight(PreflightContext const& ctx) +attestationpreflight(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureXChainBridge)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; - if (!publicKeyType(ctx.tx[sfPublicKey])) return temMALFORMED; @@ -1241,7 +1232,7 @@ attestationPreflight(PreflightContext const& ctx) if (att->sendingAmount.issue() != expectedIssue) return temXCHAIN_BAD_PROOF; - return preflight2(ctx); + return tesSUCCESS; } template @@ -1379,15 +1370,6 @@ attestationDoApply(ApplyContext& ctx) NotTEC XChainCreateBridge::preflight(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureXChainBridge)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; - auto const account = ctx.tx[sfAccount]; auto const reward = ctx.tx[sfSignatureReward]; auto const minAccountCreate = ctx.tx[~sfMinAccountCreateAmount]; @@ -1457,7 +1439,7 @@ XChainCreateBridge::preflight(PreflightContext const& ctx) return temXCHAIN_BRIDGE_BAD_ISSUES; } - return preflight2(ctx); + return tesSUCCESS; } TER @@ -1557,18 +1539,15 @@ XChainCreateBridge::doApply() //------------------------------------------------------------------------------ +std::uint32_t +BridgeModify::getFlagsMask(PreflightContext const& ctx) +{ + return tfBridgeModifyMask; +} + NotTEC BridgeModify::preflight(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureXChainBridge)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfBridgeModifyMask) - return temINVALID_FLAG; - auto const account = ctx.tx[sfAccount]; auto const reward = ctx.tx[~sfSignatureReward]; auto const minAccountCreate = ctx.tx[~sfMinAccountCreateAmount]; @@ -1607,7 +1586,7 @@ BridgeModify::preflight(PreflightContext const& ctx) return temXCHAIN_BRIDGE_BAD_MIN_ACCOUNT_CREATE_AMOUNT; } - return preflight2(ctx); + return tesSUCCESS; } TER @@ -1670,15 +1649,6 @@ BridgeModify::doApply() NotTEC XChainClaim::preflight(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureXChainBridge)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; - STXChainBridge const bridgeSpec = ctx.tx[sfXChainBridge]; auto const amount = ctx.tx[sfAmount]; @@ -1689,7 +1659,7 @@ XChainClaim::preflight(PreflightContext const& ctx) return temBAD_AMOUNT; } - return preflight2(ctx); + return tesSUCCESS; } TER @@ -1908,15 +1878,6 @@ XChainCommit::makeTxConsequences(PreflightContext const& ctx) NotTEC XChainCommit::preflight(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureXChainBridge)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; - auto const amount = ctx.tx[sfAmount]; auto const bridgeSpec = ctx.tx[sfXChainBridge]; @@ -1927,7 +1888,7 @@ XChainCommit::preflight(PreflightContext const& ctx) amount.issue() != bridgeSpec.issuingChainIssue()) return temBAD_ISSUER; - return preflight2(ctx); + return tesSUCCESS; } TER @@ -2022,21 +1983,12 @@ XChainCommit::doApply() NotTEC XChainCreateClaimID::preflight(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureXChainBridge)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; - auto const reward = ctx.tx[sfSignatureReward]; if (!isXRP(reward) || reward.signum() < 0 || !isLegalNet(reward)) return temXCHAIN_BRIDGE_BAD_REWARD_AMOUNT; - return preflight2(ctx); + return tesSUCCESS; } TER @@ -2137,7 +2089,7 @@ XChainCreateClaimID::doApply() NotTEC XChainAddClaimAttestation::preflight(PreflightContext const& ctx) { - return attestationPreflight(ctx); + return attestationpreflight(ctx); } TER @@ -2157,7 +2109,7 @@ XChainAddClaimAttestation::doApply() NotTEC XChainAddAccountCreateAttestation::preflight(PreflightContext const& ctx) { - return attestationPreflight(ctx); + return attestationpreflight(ctx); } TER @@ -2177,15 +2129,6 @@ XChainAddAccountCreateAttestation::doApply() NotTEC XChainCreateAccountCommit::preflight(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureXChainBridge)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; - auto const amount = ctx.tx[sfAmount]; if (amount.signum() <= 0 || !amount.native()) @@ -2198,7 +2141,7 @@ XChainCreateAccountCommit::preflight(PreflightContext const& ctx) if (reward.issue() != amount.issue()) return temBAD_AMOUNT; - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/XChainBridge.h b/src/xrpld/app/tx/detail/XChainBridge.h index 82b64cc0e3..0e9c0358d2 100644 --- a/src/xrpld/app/tx/detail/XChainBridge.h +++ b/src/xrpld/app/tx/detail/XChainBridge.h @@ -58,6 +58,9 @@ public: { } + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC preflight(PreflightContext const& ctx); diff --git a/src/xrpld/app/tx/detail/applySteps.cpp b/src/xrpld/app/tx/detail/applySteps.cpp index 543bedcd47..c2e4e13f08 100644 --- a/src/xrpld/app/tx/detail/applySteps.cpp +++ b/src/xrpld/app/tx/detail/applySteps.cpp @@ -119,7 +119,7 @@ invoke_preflight(PreflightContext const& ctx) try { return with_txn_type(ctx.tx.getTxnType(), [&]() { - auto const tec = T::preflight(ctx); + auto const tec = Transactor::invokePreflight(ctx); return std::make_pair( tec, isTesSuccess(tec) ? consequences_helper(ctx) From 550f90a75ec54a12ad340a4fec24ce5698cdfe3a Mon Sep 17 00:00:00 2001 From: Ed Hennis Date: Mon, 29 Sep 2025 18:11:53 -0400 Subject: [PATCH 4/6] refactor: Add support for extra transaction signatures (#5594) * Restructures Transactor signature checking code to be able to handle a `sigObject`, which may be the full transaction, or may be an object field containing a separate signature. Either way, the `sigObject` can be a single- or multi-sign signature. --- src/xrpld/app/tx/detail/Transactor.cpp | 99 ++++++++++++++------------ src/xrpld/app/tx/detail/Transactor.h | 19 ++--- 2 files changed, 64 insertions(+), 54 deletions(-) diff --git a/src/xrpld/app/tx/detail/Transactor.cpp b/src/xrpld/app/tx/detail/Transactor.cpp index 1c98233964..112017ebaf 100644 --- a/src/xrpld/app/tx/detail/Transactor.cpp +++ b/src/xrpld/app/tx/detail/Transactor.cpp @@ -659,16 +659,19 @@ Transactor::apply() } NotTEC -Transactor::checkSign(PreclaimContext const& ctx) +Transactor::checkSign( + PreclaimContext const& ctx, + AccountID const& idAccount, + STObject const& sigObject) { - auto const pkSigner = ctx.tx.getSigningPubKey(); + auto const pkSigner = sigObject.getFieldVL(sfSigningPubKey); // Ignore signature check on batch inner transactions - if (ctx.tx.isFlag(tfInnerBatchTxn) && + if (sigObject.isFlag(tfInnerBatchTxn) && ctx.view.rules().enabled(featureBatch)) { // Defensive Check: These values are also checked in Batch::preflight - if (ctx.tx.isFieldPresent(sfTxnSignature) || !pkSigner.empty() || - ctx.tx.isFieldPresent(sfSigners)) + if (sigObject.isFieldPresent(sfTxnSignature) || !pkSigner.empty() || + sigObject.isFieldPresent(sfSigners)) { return temINVALID_FLAG; // LCOV_EXCL_LINE } @@ -676,34 +679,31 @@ Transactor::checkSign(PreclaimContext const& ctx) } if ((ctx.flags & tapDRY_RUN) && pkSigner.empty() && - !ctx.tx.isFieldPresent(sfSigners)) + !sigObject.isFieldPresent(sfSigners)) { // simulate: skip signature validation when neither SigningPubKey nor // Signers are provided return tesSUCCESS; } - auto const idAccount = ctx.tx[~sfDelegate].value_or(ctx.tx[sfAccount]); - // If the pk is empty and not simulate or simulate and signers, // then we must be multi-signing. if (ctx.tx.isFieldPresent(sfSigners)) { - STArray const& txSigners(ctx.tx.getFieldArray(sfSigners)); - return checkMultiSign(ctx.view, idAccount, txSigners, ctx.flags, ctx.j); + return checkMultiSign(ctx, idAccount, sigObject); } // Check Single Sign XRPL_ASSERT( - !pkSigner.empty(), - "ripple::Transactor::checkSingleSign : non-empty signer or simulation"); + !pkSigner.empty(), "ripple::Transactor::checkSign : non-empty signer"); if (!publicKeyType(makeSlice(pkSigner))) { - JLOG(ctx.j.trace()) - << "checkSingleSign: signing public key type is unknown"; + JLOG(ctx.j.trace()) << "checkSign: signing public key type is unknown"; return tefBAD_AUTH; // FIXME: should be better error! } + + // Look up the account. auto const idSigner = pkSigner.empty() ? idAccount : calcAccountID(PublicKey(makeSlice(pkSigner))); @@ -711,8 +711,16 @@ Transactor::checkSign(PreclaimContext const& ctx) if (!sleAccount) return terNO_ACCOUNT; - return checkSingleSign( - idSigner, idAccount, sleAccount, ctx.view.rules(), ctx.j); + return checkSingleSign(ctx, idSigner, idAccount, sleAccount); +} + +NotTEC +Transactor::checkSign(PreclaimContext const& ctx) +{ + auto const idAccount = ctx.tx.isFieldPresent(sfDelegate) + ? ctx.tx.getAccountID(sfDelegate) + : ctx.tx.getAccountID(sfAccount); + return checkSign(ctx, idAccount, ctx.tx); } NotTEC @@ -727,9 +735,7 @@ Transactor::checkBatchSign(PreclaimContext const& ctx) Blob const& pkSigner = signer.getFieldVL(sfSigningPubKey); if (pkSigner.empty()) { - STArray const& txSigners(signer.getFieldArray(sfSigners)); - if (ret = checkMultiSign( - ctx.view, idAccount, txSigners, ctx.flags, ctx.j); + if (ret = checkMultiSign(ctx, idAccount, signer); !isTesSuccess(ret)) return ret; } @@ -753,8 +759,7 @@ Transactor::checkBatchSign(PreclaimContext const& ctx) return tesSUCCESS; } - if (ret = checkSingleSign( - idSigner, idAccount, sleAccount, ctx.view.rules(), ctx.j); + if (ret = checkSingleSign(ctx, idSigner, idAccount, sleAccount); !isTesSuccess(ret)) return ret; } @@ -764,15 +769,14 @@ Transactor::checkBatchSign(PreclaimContext const& ctx) NotTEC Transactor::checkSingleSign( + PreclaimContext const& ctx, AccountID const& idSigner, AccountID const& idAccount, - std::shared_ptr sleAccount, - Rules const& rules, - beast::Journal j) + std::shared_ptr sleAccount) { bool const isMasterDisabled = sleAccount->isFlag(lsfDisableMaster); - if (rules.enabled(fixMasterKeyAsRegularKey)) + if (ctx.view.rules().enabled(fixMasterKeyAsRegularKey)) { // Signed with regular key. if ((*sleAccount)[~sfRegularKey] == idSigner) @@ -809,14 +813,16 @@ Transactor::checkSingleSign( else if (sleAccount->isFieldPresent(sfRegularKey)) { // Signing key does not match master or regular key. - JLOG(j.trace()) << "checkSingleSign: Not authorized to use account."; + JLOG(ctx.j.trace()) + << "checkSingleSign: Not authorized to use account."; return tefBAD_AUTH; } else { // No regular key on account and signing key does not match master key. // FIXME: Why differentiate this case from tefBAD_AUTH? - JLOG(j.trace()) << "checkSingleSign: Not authorized to use account."; + JLOG(ctx.j.trace()) + << "checkSingleSign: Not authorized to use account."; return tefBAD_AUTH_MASTER; } @@ -825,19 +831,17 @@ Transactor::checkSingleSign( NotTEC Transactor::checkMultiSign( - ReadView const& view, + PreclaimContext const& ctx, AccountID const& id, - STArray const& txSigners, - ApplyFlags const& flags, - beast::Journal j) + STObject const& sigObject) { - // Get mTxnAccountID's SignerList and Quorum. + // Get id's SignerList and Quorum. std::shared_ptr sleAccountSigners = - view.read(keylet::signers(id)); + ctx.view.read(keylet::signers(id)); // If the signer list doesn't exist the account is not multi-signing. if (!sleAccountSigners) { - JLOG(j.trace()) + JLOG(ctx.j.trace()) << "applyTransaction: Invalid: Not a multi-signing account."; return tefNOT_MULTI_SIGNING; } @@ -852,11 +856,12 @@ Transactor::checkMultiSign( "ripple::Transactor::checkMultiSign : signer list ID is 0"); auto accountSigners = - SignerEntries::deserialize(*sleAccountSigners, j, "ledger"); + SignerEntries::deserialize(*sleAccountSigners, ctx.j, "ledger"); if (!accountSigners) return accountSigners.error(); // Get the array of transaction signers. + STArray const& txSigners(sigObject.getFieldArray(sfSigners)); // Walk the accountSigners performing a variety of checks and see if // the quorum is met. @@ -875,7 +880,7 @@ Transactor::checkMultiSign( { if (++iter == accountSigners->end()) { - JLOG(j.trace()) + JLOG(ctx.j.trace()) << "applyTransaction: Invalid SigningAccount.Account."; return tefBAD_SIGNATURE; } @@ -883,7 +888,7 @@ Transactor::checkMultiSign( if (iter->account != txSignerAcctID) { // The SigningAccount is not in the SignerEntries. - JLOG(j.trace()) + JLOG(ctx.j.trace()) << "applyTransaction: Invalid SigningAccount.Account."; return tefBAD_SIGNATURE; } @@ -897,13 +902,13 @@ Transactor::checkMultiSign( // STTx::checkMultiSign if (!spk.empty() && !publicKeyType(makeSlice(spk))) { - JLOG(j.trace()) + JLOG(ctx.j.trace()) << "checkMultiSign: signing public key type is unknown"; return tefBAD_SIGNATURE; } XRPL_ASSERT( - (flags & tapDRY_RUN) || !spk.empty(), + (ctx.flags & tapDRY_RUN) || !spk.empty(), "ripple::Transactor::checkMultiSign : non-empty signer or " "simulation"); AccountID const signingAcctIDFromPubKey = spk.empty() @@ -935,7 +940,8 @@ Transactor::checkMultiSign( // In any of these cases we need to know whether the account is in // the ledger. Determine that now. - auto const sleTxSignerRoot = view.read(keylet::account(txSignerAcctID)); + auto const sleTxSignerRoot = + ctx.view.read(keylet::account(txSignerAcctID)); if (signingAcctIDFromPubKey == txSignerAcctID) { @@ -948,7 +954,7 @@ Transactor::checkMultiSign( if (signerAccountFlags & lsfDisableMaster) { - JLOG(j.trace()) + JLOG(ctx.j.trace()) << "applyTransaction: Signer:Account lsfDisableMaster."; return tefMASTER_DISABLED; } @@ -960,21 +966,21 @@ Transactor::checkMultiSign( // Public key must hash to the account's regular key. if (!sleTxSignerRoot) { - JLOG(j.trace()) << "applyTransaction: Non-phantom signer " - "lacks account root."; + JLOG(ctx.j.trace()) << "applyTransaction: Non-phantom signer " + "lacks account root."; return tefBAD_SIGNATURE; } if (!sleTxSignerRoot->isFieldPresent(sfRegularKey)) { - JLOG(j.trace()) + JLOG(ctx.j.trace()) << "applyTransaction: Account lacks RegularKey."; return tefBAD_SIGNATURE; } if (signingAcctIDFromPubKey != sleTxSignerRoot->getAccountID(sfRegularKey)) { - JLOG(j.trace()) + JLOG(ctx.j.trace()) << "applyTransaction: Account doesn't match RegularKey."; return tefBAD_SIGNATURE; } @@ -986,7 +992,8 @@ Transactor::checkMultiSign( // Cannot perform transaction if quorum is not met. if (weightSum < sleAccountSigners->getFieldU32(sfSignerQuorum)) { - JLOG(j.trace()) << "applyTransaction: Signers failed to meet quorum."; + JLOG(ctx.j.trace()) + << "applyTransaction: Signers failed to meet quorum."; return tefBAD_QUORUM; } diff --git a/src/xrpld/app/tx/detail/Transactor.h b/src/xrpld/app/tx/detail/Transactor.h index 88b0664ea2..429dcec6fc 100644 --- a/src/xrpld/app/tx/detail/Transactor.h +++ b/src/xrpld/app/tx/detail/Transactor.h @@ -281,6 +281,12 @@ protected: static XRPAmount calculateOwnerReserveFee(ReadView const& view, STTx const& tx); + static NotTEC + checkSign( + PreclaimContext const& ctx, + AccountID const& id, + STObject const& sigObject); + // Base class always returns true static bool checkExtraFeatures(PreflightContext const& ctx); @@ -317,18 +323,15 @@ private: payFee(); static NotTEC checkSingleSign( + PreclaimContext const& ctx, AccountID const& idSigner, AccountID const& idAccount, - std::shared_ptr sleAccount, - Rules const& rules, - beast::Journal j); + std::shared_ptr sleAccount); static NotTEC checkMultiSign( - ReadView const& view, - AccountID const& idAccount, - STArray const& txSigners, - ApplyFlags const& flags, - beast::Journal j); + PreclaimContext const& ctx, + AccountID const& id, + STObject const& sigObject); void trapTransaction(uint256) const; From 294e03ecf53e00043c801da4cbe8a2133b91c8e8 Mon Sep 17 00:00:00 2001 From: Ayaz Salikhov Date: Tue, 30 Sep 2025 18:15:24 +0200 Subject: [PATCH 5/6] ci: Upload artifacts during build and test in a separate job (#5817) --- .github/actions/build-test/action.yml | 96 -------------- .github/actions/print-env/action.yml | 43 +++++++ .github/scripts/strategy-matrix/generate.py | 2 +- .github/workflows/on-pr.yml | 5 +- .github/workflows/on-trigger.yml | 21 +-- .../workflows/reusable-build-test-config.yml | 69 ++++++++++ .github/workflows/reusable-build-test.yml | 121 +++--------------- .github/workflows/reusable-build.yml | 115 +++++++++++++++++ .github/workflows/reusable-test.yml | 69 ++++++++++ 9 files changed, 322 insertions(+), 219 deletions(-) delete mode 100644 .github/actions/build-test/action.yml create mode 100644 .github/actions/print-env/action.yml create mode 100644 .github/workflows/reusable-build-test-config.yml create mode 100644 .github/workflows/reusable-build.yml create mode 100644 .github/workflows/reusable-test.yml diff --git a/.github/actions/build-test/action.yml b/.github/actions/build-test/action.yml deleted file mode 100644 index cf1bac16f7..0000000000 --- a/.github/actions/build-test/action.yml +++ /dev/null @@ -1,96 +0,0 @@ -# This action build and tests the binary. The Conan dependencies must have -# already been installed (see the build-deps action). -name: Build and Test -description: "Build and test the binary." - -# Note that actions do not support 'type' and all inputs are strings, see -# https://docs.github.com/en/actions/reference/workflows-and-actions/metadata-syntax#inputs. -inputs: - build_dir: - description: "The directory where to build." - required: true - build_only: - description: 'Whether to only build or to build and test the code ("true", "false").' - required: false - default: "false" - build_type: - description: 'The build type to use ("Debug", "Release").' - required: true - cmake_args: - description: "Additional arguments to pass to CMake." - required: false - default: "" - cmake_target: - description: "The CMake target to build." - required: true - codecov_token: - description: "The Codecov token to use for uploading coverage reports." - required: false - default: "" - os: - description: 'The operating system to use for the build ("linux", "macos", "windows").' - required: true - -runs: - using: composite - steps: - - name: Configure CMake - shell: bash - working-directory: ${{ inputs.build_dir }} - run: | - echo 'Configuring CMake.' - cmake \ - -G '${{ inputs.os == 'windows' && 'Visual Studio 17 2022' || 'Ninja' }}' \ - -DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake \ - -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} \ - ${{ inputs.cmake_args }} \ - .. - - name: Build the binary - shell: bash - working-directory: ${{ inputs.build_dir }} - run: | - echo 'Building binary.' - cmake \ - --build . \ - --config ${{ inputs.build_type }} \ - --parallel $(nproc) \ - --target ${{ inputs.cmake_target }} - - name: Check linking - if: ${{ inputs.os == 'linux' }} - shell: bash - working-directory: ${{ inputs.build_dir }} - run: | - echo 'Checking linking.' - ldd ./rippled - if [ "$(ldd ./rippled | grep -E '(libstdc\+\+|libgcc)' | wc -l)" -eq 0 ]; then - echo 'The binary is statically linked.' - else - echo 'The binary is dynamically linked.' - exit 1 - fi - - name: Verify voidstar - if: ${{ contains(inputs.cmake_args, '-Dvoidstar=ON') }} - shell: bash - working-directory: ${{ inputs.build_dir }} - run: | - echo 'Verifying presence of instrumentation.' - ./rippled --version | grep libvoidstar - - name: Test the binary - if: ${{ inputs.build_only == 'false' }} - shell: bash - working-directory: ${{ inputs.build_dir }}/${{ inputs.os == 'windows' && inputs.build_type || '' }} - run: | - echo 'Testing binary.' - ./rippled --unittest --unittest-jobs $(nproc) - ctest -j $(nproc) --output-on-failure - - name: Upload coverage report - if: ${{ inputs.cmake_target == 'coverage' }} - uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3 - with: - disable_search: true - disable_telem: true - fail_ci_if_error: true - files: ${{ inputs.build_dir }}/coverage.xml - plugins: noop - token: ${{ inputs.codecov_token }} - verbose: true diff --git a/.github/actions/print-env/action.yml b/.github/actions/print-env/action.yml new file mode 100644 index 0000000000..6019a6de2f --- /dev/null +++ b/.github/actions/print-env/action.yml @@ -0,0 +1,43 @@ +name: Print build environment +description: "Print environment and some tooling versions" + +runs: + using: composite + steps: + - name: Check configuration (Windows) + if: ${{ runner.os == 'Windows' }} + shell: bash + run: | + echo 'Checking environment variables.' + set + + echo 'Checking CMake version.' + cmake --version + + echo 'Checking Conan version.' + conan --version + + - name: Check configuration (Linux and macOS) + if: ${{ runner.os == 'Linux' || runner.os == 'macOS' }} + shell: bash + run: | + echo 'Checking path.' + echo ${PATH} | tr ':' '\n' + + echo 'Checking environment variables.' + env | sort + + echo 'Checking CMake version.' + cmake --version + + echo 'Checking compiler version.' + ${{ runner.os == 'Linux' && '${CC}' || 'clang' }} --version + + echo 'Checking Conan version.' + conan --version + + echo 'Checking Ninja version.' + ninja --version + + echo 'Checking nproc version.' + nproc --version diff --git a/.github/scripts/strategy-matrix/generate.py b/.github/scripts/strategy-matrix/generate.py index ac39803fff..fd05895b0e 100755 --- a/.github/scripts/strategy-matrix/generate.py +++ b/.github/scripts/strategy-matrix/generate.py @@ -162,7 +162,7 @@ def generate_strategy_matrix(all: bool, config: Config) -> list: 'config_name': config_name, 'cmake_args': cmake_args, 'cmake_target': cmake_target, - 'build_only': 'true' if build_only else 'false', + 'build_only': build_only, 'build_type': build_type, 'os': os, 'architecture': architecture, diff --git a/.github/workflows/on-pr.yml b/.github/workflows/on-pr.yml index a206bbf041..47323ee4a7 100644 --- a/.github/workflows/on-pr.yml +++ b/.github/workflows/on-pr.yml @@ -59,8 +59,11 @@ jobs: .github/actions/build-test/** .github/actions/setup-conan/** .github/scripts/strategy-matrix/** + .github/workflows/reusable-build.yml + .github/workflows/reusable-build-test-config.yml .github/workflows/reusable-build-test.yml .github/workflows/reusable-strategy-matrix.yml + .github/workflows/reusable-test.yml .codecov.yml cmake/** conan/** @@ -105,7 +108,7 @@ jobs: with: os: ${{ matrix.os }} secrets: - codecov_token: ${{ secrets.CODECOV_TOKEN }} + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} notify-clio: needs: diff --git a/.github/workflows/on-trigger.yml b/.github/workflows/on-trigger.yml index 7b5bda021f..b06d475a4d 100644 --- a/.github/workflows/on-trigger.yml +++ b/.github/workflows/on-trigger.yml @@ -23,8 +23,11 @@ on: - ".github/actions/build-test/**" - ".github/actions/setup-conan/**" - ".github/scripts/strategy-matrix/**" + - ".github/workflows/reusable-build.yml" + - ".github/workflows/reusable-build-test-config.yml" - ".github/workflows/reusable-build-test.yml" - ".github/workflows/reusable-strategy-matrix.yml" + - ".github/workflows/reusable-test.yml" - ".codecov.yml" - "cmake/**" - "conan/**" @@ -43,22 +46,8 @@ on: schedule: - cron: "32 6 * * 1-5" - # Run when manually triggered via the GitHub UI or API. If `force_upload` is - # true, then the dependencies that were missing (`force_rebuild` is false) or - # rebuilt (`force_rebuild` is true) will be uploaded, overwriting existing - # dependencies if needed. + # Run when manually triggered via the GitHub UI or API. workflow_dispatch: - inputs: - dependencies_force_build: - description: "Force building of all dependencies." - required: false - type: boolean - default: false - dependencies_force_upload: - description: "Force uploading of all dependencies." - required: false - type: boolean - default: false concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -82,4 +71,4 @@ jobs: os: ${{ matrix.os }} strategy_matrix: ${{ github.event_name == 'schedule' && 'all' || 'minimal' }} secrets: - codecov_token: ${{ secrets.CODECOV_TOKEN }} + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/reusable-build-test-config.yml b/.github/workflows/reusable-build-test-config.yml new file mode 100644 index 0000000000..3160cef031 --- /dev/null +++ b/.github/workflows/reusable-build-test-config.yml @@ -0,0 +1,69 @@ +name: Build and test configuration + +on: + workflow_call: + inputs: + build_dir: + description: "The directory where to build." + required: true + type: string + build_only: + description: 'Whether to only build or to build and test the code ("true", "false").' + required: true + type: boolean + build_type: + description: 'The build type to use ("Debug", "Release").' + type: string + required: true + cmake_args: + description: "Additional arguments to pass to CMake." + required: false + type: string + default: "" + cmake_target: + description: "The CMake target to build." + type: string + required: true + + runs_on: + description: Runner to run the job on as a JSON string + required: true + type: string + image: + description: "The image to run in (leave empty to run natively)" + required: true + type: string + + config_name: + description: "The configuration string (used for naming artifacts and such)." + required: true + type: string + + secrets: + CODECOV_TOKEN: + description: "The Codecov token to use for uploading coverage reports." + required: true + +jobs: + build: + uses: ./.github/workflows/reusable-build.yml + with: + build_dir: ${{ inputs.build_dir }} + build_type: ${{ inputs.build_type }} + cmake_args: ${{ inputs.cmake_args }} + cmake_target: ${{ inputs.cmake_target }} + runs_on: ${{ inputs.runs_on }} + image: ${{ inputs.image }} + config_name: ${{ inputs.config_name }} + secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + + test: + needs: build + uses: ./.github/workflows/reusable-test.yml + with: + run_tests: ${{ !inputs.build_only }} + verify_voidstar: ${{ contains(inputs.cmake_args, '-Dvoidstar=ON') }} + runs_on: ${{ inputs.runs_on }} + image: ${{ inputs.image }} + config_name: ${{ inputs.config_name }} diff --git a/.github/workflows/reusable-build-test.yml b/.github/workflows/reusable-build-test.yml index 2197e88a42..c274cf2b21 100644 --- a/.github/workflows/reusable-build-test.yml +++ b/.github/workflows/reusable-build-test.yml @@ -13,16 +13,6 @@ on: required: false type: string default: ".build" - dependencies_force_build: - description: "Force building of all dependencies." - required: false - type: boolean - default: false - dependencies_force_upload: - description: "Force uploading of all dependencies." - required: false - type: boolean - default: false os: description: 'The operating system to use for the build ("linux", "macos", "windows").' required: true @@ -34,17 +24,9 @@ on: type: string default: "minimal" secrets: - codecov_token: + CODECOV_TOKEN: description: "The Codecov token to use for uploading coverage reports." - required: false - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }}-${{ inputs.os }} - cancel-in-progress: true - -defaults: - run: - shell: bash + required: true jobs: # Generate the strategy matrix to be used by the following job. @@ -54,94 +36,23 @@ jobs: os: ${{ inputs.os }} strategy_matrix: ${{ inputs.strategy_matrix }} - # Build and test the binary. - build-test: + # Build and test the binary for each configuration. + build-test-config: needs: - generate-matrix + uses: ./.github/workflows/reusable-build-test-config.yml strategy: fail-fast: false matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }} max-parallel: 10 - runs-on: ${{ matrix.architecture.runner }} - container: ${{ inputs.os == 'linux' && format('ghcr.io/xrplf/ci/{0}-{1}:{2}-{3}-sha-5dd7158', matrix.os.distro_name, matrix.os.distro_version, matrix.os.compiler_name, matrix.os.compiler_version) || null }} - steps: - - name: Check strategy matrix - run: | - echo 'Operating system distro name: ${{ matrix.os.distro_name }}' - echo 'Operating system distro version: ${{ matrix.os.distro_version }}' - echo 'Operating system compiler name: ${{ matrix.os.compiler_name }}' - echo 'Operating system compiler version: ${{ matrix.os.compiler_version }}' - echo 'Architecture platform: ${{ matrix.architecture.platform }}' - echo 'Architecture runner: ${{ toJson(matrix.architecture.runner) }}' - echo 'Build type: ${{ matrix.build_type }}' - echo 'Build only: ${{ matrix.build_only }}' - echo 'CMake arguments: ${{ matrix.cmake_args }}' - echo 'CMake target: ${{ matrix.cmake_target }}' - echo 'Config name: ${{ matrix.config_name }}' - - - name: Cleanup workspace - if: ${{ runner.os == 'macOS' }} - uses: XRPLF/actions/.github/actions/cleanup-workspace@3f044c7478548e3c32ff68980eeb36ece02b364e - - - name: Checkout repository - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 - - name: Prepare runner - uses: XRPLF/actions/.github/actions/prepare-runner@638e0dc11ea230f91bd26622fb542116bb5254d5 - with: - disable_ccache: false - - - name: Check configuration (Windows) - if: ${{ inputs.os == 'windows' }} - run: | - echo 'Checking environment variables.' - set - - echo 'Checking CMake version.' - cmake --version - - echo 'Checking Conan version.' - conan --version - - name: Check configuration (Linux and MacOS) - if: ${{ inputs.os == 'linux' || inputs.os == 'macos' }} - run: | - echo 'Checking path.' - echo ${PATH} | tr ':' '\n' - - echo 'Checking environment variables.' - env | sort - - echo 'Checking CMake version.' - cmake --version - - echo 'Checking compiler version.' - ${{ inputs.os == 'linux' && '${CC}' || 'clang' }} --version - - echo 'Checking Conan version.' - conan --version - - echo 'Checking Ninja version.' - ninja --version - - echo 'Checking nproc version.' - nproc --version - - - name: Setup Conan - uses: ./.github/actions/setup-conan - - - name: Build dependencies - uses: ./.github/actions/build-deps - with: - build_dir: ${{ inputs.build_dir }} - build_type: ${{ matrix.build_type }} - force_build: ${{ inputs.dependencies_force_build }} - - - name: Build and test binary - uses: ./.github/actions/build-test - with: - build_dir: ${{ inputs.build_dir }} - build_only: ${{ matrix.build_only }} - build_type: ${{ matrix.build_type }} - cmake_args: ${{ matrix.cmake_args }} - cmake_target: ${{ matrix.cmake_target }} - codecov_token: ${{ secrets.codecov_token }} - os: ${{ inputs.os }} + with: + build_dir: ${{ inputs.build_dir }} + build_only: ${{ matrix.build_only }} + build_type: ${{ matrix.build_type }} + cmake_args: ${{ matrix.cmake_args }} + cmake_target: ${{ matrix.cmake_target }} + runs_on: ${{ toJSON(matrix.architecture.runner) }} + image: ${{ contains(matrix.architecture.platform, 'linux') && format('ghcr.io/xrplf/ci/{0}-{1}:{2}-{3}-sha-5dd7158', matrix.os.distro_name, matrix.os.distro_version, matrix.os.compiler_name, matrix.os.compiler_version) || '' }} + config_name: ${{ matrix.config_name }} + secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/reusable-build.yml b/.github/workflows/reusable-build.yml new file mode 100644 index 0000000000..e586917374 --- /dev/null +++ b/.github/workflows/reusable-build.yml @@ -0,0 +1,115 @@ +name: Build rippled + +on: + workflow_call: + inputs: + build_dir: + description: "The directory where to build." + required: true + type: string + build_type: + description: 'The build type to use ("Debug", "Release").' + required: true + type: string + cmake_args: + description: "Additional arguments to pass to CMake." + required: true + type: string + cmake_target: + description: "The CMake target to build." + required: true + type: string + + runs_on: + description: Runner to run the job on as a JSON string + required: true + type: string + image: + description: "The image to run in (leave empty to run natively)" + required: true + type: string + + config_name: + description: "The name of the configuration." + required: true + type: string + + secrets: + CODECOV_TOKEN: + description: "The Codecov token to use for uploading coverage reports." + required: true + +defaults: + run: + shell: bash + +jobs: + build: + name: Build ${{ inputs.config_name }} + runs-on: ${{ fromJSON(inputs.runs_on) }} + container: ${{ inputs.image != '' && inputs.image || null }} + steps: + - name: Cleanup workspace + if: ${{ runner.os == 'macOS' }} + uses: XRPLF/actions/.github/actions/cleanup-workspace@3f044c7478548e3c32ff68980eeb36ece02b364e + + - name: Checkout repository + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + + - name: Prepare runner + uses: XRPLF/actions/.github/actions/prepare-runner@638e0dc11ea230f91bd26622fb542116bb5254d5 + with: + disable_ccache: false + + - name: Print build environment + uses: ./.github/actions/print-env + + - name: Setup Conan + uses: ./.github/actions/setup-conan + + - name: Build dependencies + uses: ./.github/actions/build-deps + with: + build_dir: ${{ inputs.build_dir }} + build_type: ${{ inputs.build_type }} + + - name: Configure CMake + shell: bash + working-directory: ${{ inputs.build_dir }} + run: | + cmake \ + -G '${{ runner.os == 'Windows' && 'Visual Studio 17 2022' || 'Ninja' }}' \ + -DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake \ + -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} \ + ${{ inputs.cmake_args }} \ + .. + + - name: Build the binary + shell: bash + working-directory: ${{ inputs.build_dir }} + run: | + cmake \ + --build . \ + --config ${{ inputs.build_type }} \ + --parallel $(nproc) \ + --target ${{ inputs.cmake_target }} + + - name: Upload rippled artifact + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: rippled-${{ inputs.config_name }} + path: ${{ inputs.build_dir }}/${{ runner.os == 'Windows' && inputs.build_type || '' }}/rippled${{ runner.os == 'Windows' && '.exe' || '' }} + retention-days: 3 + if-no-files-found: error + + - name: Upload coverage report + if: ${{ inputs.cmake_target == 'coverage' }} + uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3 + with: + disable_search: true + disable_telem: true + fail_ci_if_error: true + files: ${{ inputs.build_dir }}/coverage.xml + plugins: noop + token: ${{ secrets.CODECOV_TOKEN }} + verbose: true diff --git a/.github/workflows/reusable-test.yml b/.github/workflows/reusable-test.yml new file mode 100644 index 0000000000..1877a19a72 --- /dev/null +++ b/.github/workflows/reusable-test.yml @@ -0,0 +1,69 @@ +name: Test rippled + +on: + workflow_call: + inputs: + verify_voidstar: + description: "Whether to verify the presence of voidstar instrumentation." + required: true + type: boolean + run_tests: + description: "Whether to run unit tests" + required: true + type: boolean + + runs_on: + description: Runner to run the job on as a JSON string + required: true + type: string + image: + description: "The image to run in (leave empty to run natively)" + required: true + type: string + + config_name: + description: "The name of the configuration." + required: true + type: string + +jobs: + test: + name: Test ${{ inputs.config_name }} + runs-on: ${{ fromJSON(inputs.runs_on) }} + container: ${{ inputs.image != '' && inputs.image || null }} + steps: + - name: Download rippled artifact + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 + with: + name: rippled-${{ inputs.config_name }} + + - name: Make binary executable (Linux and macOS) + shell: bash + if: ${{ runner.os == 'Linux' || runner.os == 'macOS' }} + run: | + chmod +x ./rippled + + - name: Check linking (Linux) + if: ${{ runner.os == 'Linux' }} + shell: bash + run: | + ldd ./rippled + if [ "$(ldd ./rippled | grep -E '(libstdc\+\+|libgcc)' | wc -l)" -eq 0 ]; then + echo 'The binary is statically linked.' + else + echo 'The binary is dynamically linked.' + exit 1 + fi + + - name: Verifying presence of instrumentation + if: ${{ inputs.verify_voidstar }} + shell: bash + run: | + ./rippled --version | grep libvoidstar + + - name: Test the binary + if: ${{ inputs.run_tests }} + shell: bash + run: | + ./rippled --unittest --unittest-jobs $(nproc) + ctest -j $(nproc) --output-on-failure From 072b1c442c11230f6c82a7a32017ff699134176a Mon Sep 17 00:00:00 2001 From: Bart Date: Tue, 30 Sep 2025 19:46:10 +0200 Subject: [PATCH 6/6] chore: Set free-form CI inputs as env vars (#5822) This change moves CI values that could be user-provided into environment variables. --- .github/actions/build-deps/action.yml | 16 ++++++++++------ .github/actions/setup-conan/action.yml | 7 +++++-- .github/workflows/reusable-build.yml | 14 ++++++++++---- .github/workflows/reusable-notify-clio.yml | 17 ++++++++++------- .github/workflows/reusable-strategy-matrix.yml | 5 ++++- .github/workflows/upload-conan-deps.yml | 7 +++---- 6 files changed, 42 insertions(+), 24 deletions(-) diff --git a/.github/actions/build-deps/action.yml b/.github/actions/build-deps/action.yml index 351d8a6361..a908c656e8 100644 --- a/.github/actions/build-deps/action.yml +++ b/.github/actions/build-deps/action.yml @@ -20,14 +20,18 @@ runs: steps: - name: Install Conan dependencies shell: bash + env: + BUILD_DIR: ${{ inputs.build_dir }} + BUILD_OPTION: ${{ inputs.force_build == 'true' && '*' || 'missing' }} + BUILD_TYPE: ${{ inputs.build_type }} run: | echo 'Installing dependencies.' - mkdir -p ${{ inputs.build_dir }} - cd ${{ inputs.build_dir }} + mkdir -p '${{ env.BUILD_DIR }}' + cd '${{ env.BUILD_DIR }}' conan install \ --output-folder . \ - --build ${{ inputs.force_build == 'true' && '"*"' || 'missing' }} \ - --options:host '&:tests=True' \ - --options:host '&:xrpld=True' \ - --settings:all build_type=${{ inputs.build_type }} \ + --build=${{ env.BUILD_OPTION }} \ + --options:host='&:tests=True' \ + --options:host='&:xrpld=True' \ + --settings:all build_type='${{ env.BUILD_TYPE }}' \ .. diff --git a/.github/actions/setup-conan/action.yml b/.github/actions/setup-conan/action.yml index d31809dc94..02061c7a64 100644 --- a/.github/actions/setup-conan/action.yml +++ b/.github/actions/setup-conan/action.yml @@ -35,9 +35,12 @@ runs: - name: Set up Conan remote shell: bash + env: + CONAN_REMOTE_NAME: ${{ inputs.conan_remote_name }} + CONAN_REMOTE_URL: ${{ inputs.conan_remote_url }} run: | - echo "Adding Conan remote '${{ inputs.conan_remote_name }}' at ${{ inputs.conan_remote_url }}." - conan remote add --index 0 --force ${{ inputs.conan_remote_name }} ${{ inputs.conan_remote_url }} + echo "Adding Conan remote '${{ env.CONAN_REMOTE_NAME }}' at '${{ env.CONAN_REMOTE_URL }}'." + conan remote add --index 0 --force '${{ env.CONAN_REMOTE_NAME }}' '${{ env.CONAN_REMOTE_URL }}' echo 'Listing Conan remotes.' conan remote list diff --git a/.github/workflows/reusable-build.yml b/.github/workflows/reusable-build.yml index e586917374..9c994598c2 100644 --- a/.github/workflows/reusable-build.yml +++ b/.github/workflows/reusable-build.yml @@ -76,23 +76,29 @@ jobs: - name: Configure CMake shell: bash working-directory: ${{ inputs.build_dir }} + env: + BUILD_TYPE: ${{ inputs.build_type }} + CMAKE_ARGS: ${{ inputs.cmake_args }} run: | cmake \ -G '${{ runner.os == 'Windows' && 'Visual Studio 17 2022' || 'Ninja' }}' \ -DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake \ - -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} \ - ${{ inputs.cmake_args }} \ + -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \ + ${{ env.CMAKE_ARGS }} \ .. - name: Build the binary shell: bash working-directory: ${{ inputs.build_dir }} + env: + BUILD_TYPE: ${{ inputs.build_type }} + CMAKE_TARGET: ${{ inputs.cmake_target }} run: | cmake \ --build . \ - --config ${{ inputs.build_type }} \ + --config ${{ env.BUILD_TYPE }} \ --parallel $(nproc) \ - --target ${{ inputs.cmake_target }} + --target ${{ env.CMAKE_TARGET }} - name: Upload rippled artifact uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 diff --git a/.github/workflows/reusable-notify-clio.yml b/.github/workflows/reusable-notify-clio.yml index 2d6fa63796..99009d953e 100644 --- a/.github/workflows/reusable-notify-clio.yml +++ b/.github/workflows/reusable-notify-clio.yml @@ -46,41 +46,44 @@ jobs: uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 - name: Generate outputs id: generate + env: + PR_NUMBER: ${{ github.event.pull_request.number }} run: | echo 'Generating user and channel.' echo "user=clio" >> "${GITHUB_OUTPUT}" - echo "channel=pr_${{ github.event.pull_request.number }}" >> "${GITHUB_OUTPUT}" + echo "channel=pr_${{ env.PR_NUMBER }}" >> "${GITHUB_OUTPUT}" echo 'Extracting version.' echo "version=$(cat src/libxrpl/protocol/BuildInfo.cpp | grep "versionString =" | awk -F '"' '{print $2}')" >> "${GITHUB_OUTPUT}" - name: Calculate conan reference id: conan_ref run: | echo "conan_ref=${{ steps.generate.outputs.version }}@${{ steps.generate.outputs.user }}/${{ steps.generate.outputs.channel }}" >> "${GITHUB_OUTPUT}" - - name: Set up Conan uses: ./.github/actions/setup-conan with: conan_remote_name: ${{ inputs.conan_remote_name }} conan_remote_url: ${{ inputs.conan_remote_url }} - - name: Log into Conan remote run: conan remote login ${{ inputs.conan_remote_name }} "${{ secrets.conan_remote_username }}" --password "${{ secrets.conan_remote_password }}" - name: Upload package + env: + CONAN_REMOTE_NAME: ${{ inputs.conan_remote_name }} run: | conan export --user=${{ steps.generate.outputs.user }} --channel=${{ steps.generate.outputs.channel }} . - conan upload --confirm --check --remote=${{ inputs.conan_remote_name }} xrpl/${{ steps.conan_ref.outputs.conan_ref }} + conan upload --confirm --check --remote=${{ env.CONAN_REMOTE_NAME }} xrpl/${{ steps.conan_ref.outputs.conan_ref }} outputs: conan_ref: ${{ steps.conan_ref.outputs.conan_ref }} notify: needs: upload runs-on: ubuntu-latest - env: - GH_TOKEN: ${{ secrets.clio_notify_token }} steps: - name: Notify Clio + env: + GH_TOKEN: ${{ secrets.clio_notify_token }} + PR_URL: ${{ github.event.pull_request.html_url }} run: | gh api --method POST -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" \ /repos/xrplf/clio/dispatches -f "event_type=check_libxrpl" \ -F "client_payload[conan_ref]=${{ needs.upload.outputs.conan_ref }}" \ - -F "client_payload[pr_url]=${{ github.event.pull_request.html_url }}" + -F "client_payload[pr_url]=${{ env.PR_URL }}" diff --git a/.github/workflows/reusable-strategy-matrix.yml b/.github/workflows/reusable-strategy-matrix.yml index 20a90fc2e3..e8621527c9 100644 --- a/.github/workflows/reusable-strategy-matrix.yml +++ b/.github/workflows/reusable-strategy-matrix.yml @@ -35,4 +35,7 @@ jobs: - name: Generate strategy matrix working-directory: .github/scripts/strategy-matrix id: generate - run: ./generate.py ${{ inputs.strategy_matrix == 'all' && '--all' || '' }} ${{ inputs.os != '' && format('--config={0}.json', inputs.os) || '' }} >> "${GITHUB_OUTPUT}" + env: + GENERATE_CONFIG: ${{ inputs.os != '' && format('--config={0}.json', inputs.os) || '' }} + GENERATE_OPTION: ${{ inputs.strategy_matrix == 'all' && '--all' || '' }} + run: ./generate.py ${{ env.GENERATE_OPTION }} ${{ env.GENERATE_CONFIG }} >> "${GITHUB_OUTPUT}" diff --git a/.github/workflows/upload-conan-deps.yml b/.github/workflows/upload-conan-deps.yml index 98db52a436..cbae8a4c86 100644 --- a/.github/workflows/upload-conan-deps.yml +++ b/.github/workflows/upload-conan-deps.yml @@ -24,13 +24,10 @@ on: branches: [develop] paths: - .github/workflows/upload-conan-deps.yml - - .github/workflows/reusable-strategy-matrix.yml - - .github/actions/build-deps/action.yml - .github/actions/setup-conan/action.yml - ".github/scripts/strategy-matrix/**" - - conanfile.py - conan.lock @@ -88,4 +85,6 @@ jobs: - name: Upload Conan packages if: ${{ github.repository_owner == 'XRPLF' && github.event_name != 'pull_request' && github.event_name != 'schedule' }} - run: conan upload "*" -r=${{ env.CONAN_REMOTE_NAME }} --confirm ${{ github.event.inputs.force_upload == 'true' && '--force' || '' }} + env: + FORCE_OPTION: ${{ github.event.inputs.force_upload == 'true' && '--force' || '' }} + run: conan upload "*" --remote='${{ env.CONAN_REMOTE_NAME }}' --confirm ${{ env.FORCE_OPTION }}