Skip to content

Commit bd2b448

Browse files
authored
sync code from 3.16.2 (FISCO-BCOS#5006)
2 parents 944b4d8 + 9ae7776 commit bd2b448

File tree

11 files changed

+189
-15
lines changed

11 files changed

+189
-15
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ endif()
66

77
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
88

9-
set(VERSION "3.16.1")
9+
set(VERSION "3.16.2")
1010
set(VERSION_SUFFIX "")
1111
include(Options)
1212
configure_project()

bcos-framework/bcos-framework/protocol/Protocol.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ enum ProtocolVersion : uint32_t
115115

116116
enum class BlockVersion : uint32_t
117117
{
118+
V3_16_2_VERSION = 0x03100200, // 3.16.2
118119
V3_16_1_VERSION = 0x03100100, // 3.16.1
119120
V3_16_0_VERSION = 0x03100000, // 3.16.0
120121
V3_15_4_VERSION = 0x030f0400, // 3.15.4
@@ -156,7 +157,7 @@ enum class BlockVersion : uint32_t
156157
V3_0_VERSION = 0x03000000,
157158
RC4_VERSION = 4,
158159
MIN_VERSION = RC4_VERSION,
159-
MAX_VERSION = V3_16_1_VERSION,
160+
MAX_VERSION = V3_16_2_VERSION,
160161
};
161162

162163
enum class TransactionVersion : uint32_t
@@ -171,7 +172,7 @@ const std::string RC4_VERSION_STR = "3.0.0-rc4";
171172
const std::string RC_VERSION_PREFIX = "3.0.0-rc";
172173
const std::string V3_9_VERSION_STR = "3.9.0";
173174

174-
constexpr BlockVersion DEFAULT_VERSION = bcos::protocol::BlockVersion::V3_16_1_VERSION; // 3.16.1
175+
constexpr BlockVersion DEFAULT_VERSION = bcos::protocol::BlockVersion::V3_16_2_VERSION; // 3.16.2
175176
const std::string DEFAULT_VERSION_STR = V3_9_VERSION_STR;
176177
constexpr uint8_t MAX_MAJOR_VERSION = std::numeric_limits<uint8_t>::max();
177178
constexpr uint8_t MIN_MAJOR_VERSION = 3;

bcos-rpc/bcos-rpc/web3jsonrpc/model/CallRequest.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ bcos::protocol::Transaction::Ptr CallRequest::takeToTransaction(
4040
}
4141

4242

43-
std::tuple<bool, CallRequest> rpc::decodeCallRequest(Json::Value const& _root) noexcept
43+
std::tuple<bool, CallRequest> rpc::decodeCallRequest(Json::Value const& _root)
4444
{
4545
CallRequest _request;
4646
if (!_root.isObject())
@@ -54,11 +54,15 @@ std::tuple<bool, CallRequest> rpc::decodeCallRequest(Json::Value const& _root) n
5454
}
5555
if (dataValue != nullptr)
5656
{
57-
auto const dataBytes = bcos::safeFromHexWithPrefix(dataValue->asString());
58-
_request.data = dataBytes.value();
57+
if (auto dataBytes = bcos::safeFromHexWithPrefix(dataValue->asString()))
58+
{
59+
_request.data = std::move(*dataBytes);
60+
}
61+
}
62+
if (const auto* value = _root.find("to"))
63+
{
64+
_request.to = value->asString();
5965
}
60-
_request.to = _root.isMember("to") ? _root["to"].asString() : "";
61-
6266
if (const auto* value = _root.find("from"))
6367
{
6468
_request.from = value->asString();

bcos-rpc/bcos-rpc/web3jsonrpc/model/CallRequest.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,5 +60,5 @@ struct CallRequest
6060
bcos::protocol::Transaction::Ptr takeToTransaction(
6161
bcos::protocol::TransactionFactory::Ptr const&) noexcept;
6262
};
63-
[[maybe_unused]] std::tuple<bool, CallRequest> decodeCallRequest(Json::Value const& _root) noexcept;
63+
[[maybe_unused]] std::tuple<bool, CallRequest> decodeCallRequest(Json::Value const& _root);
6464
} // namespace bcos::rpc
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
/**
2+
* Copyright (C) 2025 FISCO BCOS.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#include "bcos-rpc/web3jsonrpc/model/CallRequest.h"
7+
#include "bcos-utilities/DataConvertUtility.h"
8+
#include <json/json.h>
9+
#include <boost/test/unit_test.hpp>
10+
11+
using namespace bcos;
12+
using namespace bcos::rpc;
13+
14+
BOOST_AUTO_TEST_SUITE(testCallRequest)
15+
16+
BOOST_AUTO_TEST_CASE(decode_non_object_root)
17+
{
18+
// Given a non-object JSON value
19+
Json::Value root(Json::arrayValue);
20+
auto [ok, req] = decodeCallRequest(root);
21+
22+
// Then decode should fail and request stays default-initialized
23+
BOOST_TEST(!ok);
24+
BOOST_TEST(req.to.empty());
25+
BOOST_TEST(req.data.empty());
26+
BOOST_TEST(!req.from.has_value());
27+
BOOST_TEST(!req.gas.has_value());
28+
BOOST_TEST(!req.gasPrice.has_value());
29+
BOOST_TEST(!req.value.has_value());
30+
BOOST_TEST(!req.maxFeePerGas.has_value());
31+
BOOST_TEST(!req.maxPriorityFeePerGas.has_value());
32+
}
33+
34+
BOOST_AUTO_TEST_CASE(decode_data_and_input_precedence)
35+
{
36+
// Given both "data" and "input" present, "data" should take precedence
37+
Json::Value root(Json::objectValue);
38+
constexpr std::string_view hexData =
39+
"0x26c8917e00000000000000000000000000000000000000000000000000000000000000600000000000000000"
40+
"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
41+
"00000000000000000003e8000000000000000000000000000000000000000000000000000000000000002chszs"
42+
"ray4r2rgyr8vmossvvgh2xawx7csbmhn4gbqmwhd00000000000000000000";
43+
root["data"] = std::string{hexData};
44+
root["input"] = "0x1122";
45+
root["to"] = "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
46+
47+
auto [ok, req] = decodeCallRequest(root);
48+
BOOST_TEST(ok);
49+
50+
BOOST_TEST(req.data.empty());
51+
BOOST_CHECK_EQUAL(req.to, "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
52+
}
53+
54+
BOOST_AUTO_TEST_CASE(decode_all_fields)
55+
{
56+
// Given a full call object with all supported fields
57+
Json::Value root(Json::objectValue);
58+
root["from"] = "0x1234567890abcdef1234567890abcdef12345678";
59+
root["to"] = "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd";
60+
root["data"] = "0x010203";
61+
root["gas"] = "0x5208"; // 21000
62+
root["gasPrice"] = "0x1";
63+
root["value"] = "0x2";
64+
root["maxPriorityFeePerGas"] = "0x3";
65+
root["maxFeePerGas"] = "0x4";
66+
67+
auto [ok, req] = decodeCallRequest(root);
68+
BOOST_TEST(ok);
69+
70+
BOOST_TEST(req.from.has_value());
71+
BOOST_CHECK_EQUAL(req.from.value(), "0x1234567890abcdef1234567890abcdef12345678");
72+
BOOST_CHECK_EQUAL(req.to, "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd");
73+
constexpr std::string_view dataHex = "0x010203";
74+
BOOST_TEST(req.data == fromHexWithPrefix(dataHex));
75+
76+
BOOST_TEST(req.gas.has_value());
77+
BOOST_CHECK_EQUAL(req.gas.value(), 21000);
78+
79+
BOOST_TEST(req.gasPrice.has_value());
80+
BOOST_CHECK_EQUAL(req.gasPrice.value(), "0x1");
81+
82+
BOOST_TEST(req.value.has_value());
83+
BOOST_CHECK_EQUAL(req.value.value(), "0x2");
84+
85+
BOOST_TEST(req.maxPriorityFeePerGas.has_value());
86+
BOOST_CHECK_EQUAL(req.maxPriorityFeePerGas.value(), "0x3");
87+
88+
BOOST_TEST(req.maxFeePerGas.has_value());
89+
BOOST_CHECK_EQUAL(req.maxFeePerGas.value(), "0x4");
90+
}
91+
92+
BOOST_AUTO_TEST_CASE(decode_invalid_hex_data_is_ignored)
93+
{
94+
// Given invalid hex in data, it should be ignored (kept empty) and not throw
95+
Json::Value root(Json::objectValue);
96+
root["data"] = "0xzzzz"; // invalid hex
97+
root["to"] = "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
98+
99+
auto [ok, req] = decodeCallRequest(root);
100+
BOOST_TEST(ok);
101+
BOOST_TEST(req.data.empty());
102+
BOOST_CHECK_EQUAL(req.to, "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
103+
}
104+
105+
BOOST_AUTO_TEST_CASE(decode_uses_input_when_data_missing)
106+
{
107+
Json::Value root(Json::objectValue);
108+
root["input"] = "0xabcdef";
109+
auto [ok, req] = decodeCallRequest(root);
110+
BOOST_TEST(ok);
111+
constexpr std::string_view inputHex = "0xabcdef";
112+
BOOST_TEST(req.data == fromHexWithPrefix(inputHex));
113+
}
114+
115+
BOOST_AUTO_TEST_CASE(decode_invalid_gas_string)
116+
{
117+
Json::Value root(Json::objectValue);
118+
root["gas"] = "zz"; // invalid hex with no leading valid digit -> stoull throws -> terminate
119+
// Call function; expected to abort. If not aborted, exit(0) to mark failure in parent.
120+
BOOST_CHECK_THROW(auto resultTuple = decodeCallRequest(root), std::invalid_argument);
121+
int status = 0;
122+
}
123+
124+
BOOST_AUTO_TEST_CASE(decode_numeric_gas_treated_as_hex)
125+
{
126+
// Given gas as a numeric JSON value, asString() yields decimal text
127+
// but fromQuantity parses with base-16; verify current behavior is hex parse
128+
constexpr long long kGasDecimal = 21000;
129+
constexpr unsigned kExpectedHexParsed = 135168U; // 0x21000
130+
Json::Value root(Json::objectValue);
131+
root["gas"] = Json::Int64(kGasDecimal); // asString => "21000"; hex 0x21000 == 135168
132+
auto [ok, req] = decodeCallRequest(root);
133+
BOOST_TEST(ok);
134+
BOOST_TEST(req.gas.has_value());
135+
BOOST_CHECK_EQUAL(req.gas.value(), kExpectedHexParsed);
136+
}
137+
138+
BOOST_AUTO_TEST_CASE(decode_invalid_from_does_not_fail)
139+
{
140+
// from is passed through without validation at decode stage
141+
Json::Value root(Json::objectValue);
142+
root["from"] = "not_an_address";
143+
auto [ok, req] = decodeCallRequest(root);
144+
BOOST_TEST(ok);
145+
BOOST_TEST(req.from.has_value());
146+
BOOST_CHECK_EQUAL(req.from.value(), "not_an_address");
147+
}
148+
149+
BOOST_AUTO_TEST_CASE(decode_invalid_fee_fields_pass_through)
150+
{
151+
// gasPrice/value/max* are kept as-is; invalid strings are not parsed here
152+
Json::Value root(Json::objectValue);
153+
root["gasPrice"] = "0xzz";
154+
root["value"] = "-123";
155+
root["maxPriorityFeePerGas"] = "abc";
156+
root["maxFeePerGas"] = "\t";
157+
auto [ok, req] = decodeCallRequest(root);
158+
BOOST_TEST(ok);
159+
BOOST_TEST(req.gasPrice.has_value());
160+
BOOST_CHECK_EQUAL(req.gasPrice.value(), "0xzz");
161+
BOOST_TEST(req.value.has_value());
162+
BOOST_CHECK_EQUAL(req.value.value(), "-123");
163+
BOOST_TEST(req.maxPriorityFeePerGas.has_value());
164+
BOOST_CHECK_EQUAL(req.maxPriorityFeePerGas.value(), "abc");
165+
BOOST_TEST(req.maxFeePerGas.has_value());
166+
BOOST_CHECK_EQUAL(req.maxFeePerGas.value(), "\t");
167+
}
168+
169+
BOOST_AUTO_TEST_SUITE_END()

bcos-utilities/bcos-utilities/DataConvertUtility.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ std::optional<Out> safeFromHex(const Hex& hex, std::string_view prefix = std::st
128128
try
129129
{
130130
auto out = fromHex(hex, prefix);
131-
return std::make_optional(out);
131+
return std::make_optional(std::move(out));
132132
}
133133
catch (...)
134134
{

tools/BcosBuilder/max/conf/config-build-example.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ consensus_type = "pbft"
3636
# transaction gas limit
3737
gas_limit = "3000000000"
3838
# compatible version, can be dynamically upgraded through setSystemConfig
39-
compatibility_version = "3.16.1"
39+
compatibility_version = "3.16.2"
4040

4141
[[agency]]
4242
name = "agencyA"

tools/BcosBuilder/max/conf/config-deploy-example.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ consensus_type = "pbft"
3636
# transaction gas limit
3737
gas_limit = "3000000000"
3838
# compatible version, can be dynamically upgraded through setSystemConfig
39-
compatibility_version = "3.16.1"
39+
compatibility_version = "3.16.2"
4040

4141
[[agency]]
4242
name = "agencyA"

tools/BcosBuilder/pro/conf/config-build-example.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ consensus_type = "pbft"
3434
# transaction gas limit
3535
gas_limit = "3000000000"
3636
# compatible version, can be dynamically upgraded through setSystemConfig
37-
compatibility_version = "3.16.1"
37+
compatibility_version = "3.16.2"
3838

3939
[[agency]]
4040
name = "agencyA"

tools/BcosBuilder/pro/conf/config-deploy-example.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ consensus_type = "pbft"
3636
# transaction gas limit
3737
gas_limit = "3000000000"
3838
# compatible version, can be dynamically upgraded through setSystemConfig
39-
compatibility_version = "3.16.1"
39+
compatibility_version = "3.16.2"
4040

4141
[[agency]]
4242
name = "agencyA"

0 commit comments

Comments
 (0)