未验证 提交 3016381e 编写于 作者: D Daniel Larimer 提交者: GitHub

Merge pull request #3089 from larryk85/fix/eos3012

Fix for eos #3012 / Added code and abi sequence to action_receipt
......@@ -55,10 +55,14 @@ action_trace apply_context::exec_one()
} FC_CAPTURE_AND_RETHROW((_pending_console_output.str()));
action_receipt r;
r.receiver = receiver;
r.act_digest = digest_type::hash(act);
r.global_sequence = next_global_sequence();
r.recv_sequence = next_recv_sequence( receiver );
r.receiver = receiver;
r.act_digest = digest_type::hash(act);
r.global_sequence = next_global_sequence();
r.recv_sequence = next_recv_sequence( receiver );
const auto& account_sequence = db.get<account_sequence_object, by_name>(act.account);
r.code_sequence = account_sequence.code_sequence;
r.abi_sequence = account_sequence.abi_sequence;
for( const auto& auth : act.authorization ) {
r.auth_sequence[auth.actor] = next_auth_sequence( auth.actor );
......@@ -590,7 +594,6 @@ int apply_context::db_end_i64( uint64_t code, uint64_t scope, uint64_t table ) {
return keyval_cache.cache_table( *tab );
}
uint64_t apply_context::next_global_sequence() {
const auto& p = control.get_dynamic_global_properties();
db.modify( p, [&]( auto& dgp ) {
......
......@@ -138,8 +138,8 @@ void apply_eosio_setcode(apply_context& context) {
const auto& account = db.get<account_object,by_name>(act.account);
int64_t code_size = (int64_t)act.code.size();
int64_t old_size = (int64_t)account.code.size() * config::setcode_ram_bytes_multiplier;
int64_t new_size = code_size * config::setcode_ram_bytes_multiplier;
int64_t old_size = (int64_t)account.code.size() * config::setcode_ram_bytes_multiplier;
int64_t new_size = code_size * config::setcode_ram_bytes_multiplier;
FC_ASSERT( account.code_version != code_id, "contract is already running this version of code" );
// wlog( "set code: ${size}", ("size",act.code.size()));
......@@ -153,13 +153,18 @@ void apply_eosio_setcode(apply_context& context) {
});
const auto& account_sequence = db.get<account_sequence_object, by_name>(act.account);
db.modify( account_sequence, [&]( auto& aso ) {
aso.code_sequence += 1;
});
if (new_size != old_size) {
context.trx_context.add_ram_usage( act.account, new_size - old_size );
}
}
void apply_eosio_setabi(apply_context& context) {
auto& db = context.db;
auto& db = context.db;
auto act = context.act.data_as<setabi>();
context.require_authorization(act.account);
......@@ -183,6 +188,11 @@ void apply_eosio_setabi(apply_context& context) {
a.set_abi( act.abi );
});
const auto& account_sequence = db.get<account_sequence_object, by_name>(act.account);
db.modify( account_sequence, [&]( auto& aso ) {
aso.abi_sequence += 1;
});
if (new_size != old_size) {
context.trx_context.add_ram_usage( act.account, new_size - old_size );
}
......
......@@ -54,7 +54,6 @@ namespace eosio { namespace chain {
>
>;
class account_sequence_object : public chainbase::object<account_sequence_object_type, account_sequence_object>
{
OBJECT_CTOR(account_sequence_object);
......@@ -63,6 +62,8 @@ namespace eosio { namespace chain {
account_name name;
uint64_t recv_sequence = 0;
uint64_t auth_sequence = 0;
uint64_t code_sequence = 0;
uint64_t abi_sequence = 0;
};
struct by_name;
......
......@@ -15,12 +15,14 @@ namespace eosio { namespace chain {
account_name receiver;
digest_type act_digest;
uint64_t global_sequence = 0; ///< total number of actions dispatched since genesis
uint64_t recv_sequence = 0; ///< total number of actions with this receiver since genesis
uint64_t recv_sequence = 0; ///< total number of actions with this receiver since genesis
flat_map<account_name,uint64_t> auth_sequence;
fc::unsigned_int code_sequence = 0; ///< total number of setcodes
fc::unsigned_int abi_sequence = 0; ///< total number of setabis
digest_type digest()const { return digest_type::hash(*this); }
};
} } /// namespace eosio::chain
FC_REFLECT( eosio::chain::action_receipt, (receiver)(act_digest)(global_sequence)(recv_sequence)(auth_sequence) )
FC_REFLECT( eosio::chain::action_receipt, (receiver)(act_digest)(global_sequence)(recv_sequence)(auth_sequence)(code_sequence)(abi_sequence) )
......@@ -1670,19 +1670,27 @@ int main( int argc, char** argv ) {
string contractPath;
string wastPath;
string abiPath;
bool shouldSend = true;
auto codeSubcommand = setSubcommand->add_subcommand("code", localized("Create or update the code on an account"));
codeSubcommand->add_option("account", account, localized("The account to set code for"))->required();
codeSubcommand->add_option("code-file", wastPath, localized("The fullpath containing the contract WAST or WASM"))->required();
auto abiSubcommand = setSubcommand->add_subcommand("abi", localized("Create or update the abi on an account"));
abiSubcommand->add_option("account", account, localized("The account to set the ABI for"))->required();
abiSubcommand->add_option("abi-file", abiPath, localized("The fullpath containing the contract WAST or WASM"))->required();
auto contractSubcommand = setSubcommand->add_subcommand("contract", localized("Create or update the contract on an account"));
contractSubcommand->add_option("account", account, localized("The account to publish a contract for"))
->required();
contractSubcommand->add_option("contract-dir", contractPath, localized("The the path containing the .wast and .abi"))
contractSubcommand->add_option("contract-dir", contractPath, localized("The path containing the .wast and .abi"))
->required();
contractSubcommand->add_option("wast-file", wastPath, localized("The file containing the contract WAST or WASM relative to contract-dir"));
// ->check(CLI::ExistingFile);
auto abi = contractSubcommand->add_option("abi-file,-a,--abi", abiPath, localized("The ABI for the contract relative to contract-dir"));
// ->check(CLI::ExistingFile);
add_standard_transaction_options(contractSubcommand, "account@active");
contractSubcommand->set_callback([&] {
std::vector<chain::action> actions;
auto set_code_callback = [&]() {
std::string wast;
fc::path cpath(contractPath);
......@@ -1695,11 +1703,6 @@ int main( int argc, char** argv ) {
wastPath = (cpath / (cpath.filename().generic_string()+".wast")).generic_string();
}
if( abiPath.empty() )
{
abiPath = (cpath / (cpath.filename().generic_string()+".abi")).generic_string();
}
std::cout << localized(("Reading WAST/WASM from " + wastPath + "...").c_str()) << std::endl;
fc::read_file_contents(wastPath, wast);
FC_ASSERT( !wast.empty(), "no wast file found ${f}", ("f", wastPath) );
......@@ -1714,25 +1717,45 @@ int main( int argc, char** argv ) {
wasm = wast_to_wasm(wast);
}
std::vector<chain::action> actions;
actions.emplace_back( create_setcode(account, bytes(wasm.begin(), wasm.end()) ) );
if ( shouldSend ) {
std::cout << localized("Setting Code...") << std::endl;
send_actions(std::move(actions), 10000, packed_transaction::zlib);
}
};
auto set_abi_callback = [&]() {
fc::path cpath(contractPath);
if( cpath.filename().generic_string() == "." ) cpath = cpath.parent_path();
if( abiPath.empty() )
{
abiPath = (cpath / (cpath.filename().generic_string()+".abi")).generic_string();
}
FC_ASSERT( fc::exists( abiPath ), "no abi file found ${f}", ("f", abiPath) );
try {
actions.emplace_back( create_setabi(account, fc::json::from_file(abiPath).as<abi_def>()) );
} EOS_RETHROW_EXCEPTIONS(abi_type_exception, "Fail to parse ABI JSON")
if ( shouldSend ) {
std::cout << localized("Setting ABI...") << std::endl;
send_actions(std::move(actions), 10000, packed_transaction::zlib);
}
};
add_standard_transaction_options(contractSubcommand, "account@active");
add_standard_transaction_options(codeSubcommand, "account@active");
add_standard_transaction_options(abiSubcommand, "account@active");
contractSubcommand->set_callback([&] {
shouldSend = false;
set_code_callback();
set_abi_callback();
std::cout << localized("Publishing contract...") << std::endl;
send_actions(std::move(actions), 10000, packed_transaction::zlib);
/*
auto result = push_actions(std::move(actions), 10000, packed_transaction::zlib);
if( tx_dont_broadcast ) {
std::cout << fc::json::to_pretty_string(result) << "\n";
}
*/
});
codeSubcommand->set_callback(set_code_callback);
abiSubcommand->set_callback(set_abi_callback);
// set account
auto setAccount = setSubcommand->add_subcommand("account", localized("set or update blockchain account state"))->require_subcommand();
......
......@@ -44,6 +44,9 @@
#include <test_api_db/test_api_db.wast.hpp>
#include <test_api_multi_index/test_api_multi_index.wast.hpp>
#include <eosio.bios/eosio.bios.wast.hpp>
#include <eosio.bios/eosio.bios.abi.hpp>
#define DISABLE_EOSLIB_SERIALIZE
#include <test_api/test_api_common.hpp>
......@@ -237,6 +240,50 @@ struct MySink : public bio::sink
};
uint32_t last_fnc_err = 0;
BOOST_FIXTURE_TEST_CASE(action_receipt_tests, TESTER) { try {
produce_blocks(2);
create_account( N(testapi) );
create_account( N(testapi2) );
produce_blocks(10);
set_code( N(testapi), test_api_wast );
produce_blocks(1);
auto res = CALL_TEST_FUNCTION( *this, "test_action", "assert_true", {});
BOOST_REQUIRE_EQUAL(uint32_t(res->action_traces[0].receipt.code_sequence), 1);
BOOST_REQUIRE_EQUAL(uint32_t(res->action_traces[0].receipt.abi_sequence), 0);
set_code( N(testapi), test_api_db_wast );
set_code( config::system_account_name, test_api_db_wast );
res = CALL_TEST_FUNCTION( *this, "test_db", "primary_i64_general", {});
BOOST_REQUIRE_EQUAL(uint32_t(res->action_traces[0].receipt.code_sequence), 2);
BOOST_REQUIRE_EQUAL(uint32_t(res->action_traces[0].receipt.abi_sequence), 0);
{
signed_transaction trx;
auto pl = vector<permission_level>{{config::system_account_name, config::active_name}};
action act(pl, test_chain_action<TEST_METHOD("test_db", "primary_i64_general")>{});
act.authorization = {{config::system_account_name, config::active_name}};
trx.actions.push_back(act);
this->set_transaction_headers(trx, this->DEFAULT_EXPIRATION_DELTA);
trx.sign(this->get_private_key(config::system_account_name, "active"), chain_id_type());
trx.get_signature_keys(chain_id_type() );
auto res = this->push_transaction(trx);
BOOST_CHECK_EQUAL(res->receipt->status, transaction_receipt::executed);
this->produce_block();
BOOST_REQUIRE_EQUAL(uint32_t(res->action_traces[0].receipt.code_sequence), 2);
BOOST_REQUIRE_EQUAL(uint32_t(res->action_traces[0].receipt.abi_sequence), 1);
}
set_code( config::system_account_name, eosio_bios_wast );
set_code( N(testapi), eosio_bios_wast );
set_abi(N(testapi), eosio_bios_abi);
set_code( N(testapi), test_api_wast );
res = CALL_TEST_FUNCTION( *this, "test_action", "assert_true", {});
BOOST_REQUIRE_EQUAL(uint32_t(res->action_traces[0].receipt.code_sequence), 4);
BOOST_REQUIRE_EQUAL(uint32_t(res->action_traces[0].receipt.abi_sequence), 1);
} FC_LOG_AND_RETHROW() }
/*************************************************************************************
* action_tests test case
*************************************************************************************/
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册