推送交易上链“假”失败的处理方案
解决问题
对于通过Rpc推送交易上链,因超时等因素导致无返回交易id或者失败,实际交易已上链。
解决方案
在推送交易时附加一个action,action可以填一个与此次推送任务对应的唯一值mark
,并把当前链的块高度记下
void addmark( const name& owner, const string& mark )
{
require_auth( owner );
}
然后mongo会把这个action数据以及对应的交易Id 洗出来
bool
mongo_db_plugin_impl::add_action_trace( mongocxx::bulk_write& bulk_action_traces, const chain::action_trace& atrace,
const chain::transaction_trace_ptr& t,
bool executed, const std::chrono::milliseconds& now,
bool& write_ttrace )
{
using namespace bsoncxx::types;
using bsoncxx::builder::basic::kvp;
const auto block_time = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::microseconds{atrace.block_time.to_time_point().time_since_epoch().count()} );
if( executed && atrace.receipt->receiver == chain::config::system_account_name ) {
update_account( atrace, now, block_time );
}
.....
else if(atrace.act.name == name("addmark")) {
add_trx_marks( atrace, now, block_time );
}
void mongo_db_plugin_impl::add_trx_marks( const chain::action_trace& atrace, const std::chrono::milliseconds& now, const std::chrono::milliseconds& block_time ) {
using namespace bsoncxx::types;
using bsoncxx::builder::basic::kvp;
using bsoncxx::builder::basic::make_document;
auto addma = fc::raw::unpack<mongo_db_plugin::addmark>(atrace.act.data);
auto doc = make_document(
kvp( "mark", addma.mark),
kvp( "trx_id", atrace.trx_id.str()),
kvp( "owner", addma.owner.to_string()),
kvp( "contract",atrace.receipt.receiver.to_string()),
kvp( "block_time", b_date{block_time}),
kvp( "block_timestamp", block_time.count()),
kvp( "createdAt", b_date{now} ));
try {
if( !_trx_marks.insert_one(doc.view())) {
EOS_ASSERT( false, chain::mongo_db_insert_fail, "Failed to insert _trx_marks ${name} : ${mark}", ("name", addma.owner.to_string())("mark", addma.mark) );
}
} catch (...) {
handle_mongo_exception( "_trx_marks", __LINE__ );
}
}
测试查询记录
也就是如果推送没返回交易id,可以尝试查洗出的这个表,如果有的话,使用对应的交易id做数据补全。
{
"_id" : ObjectId("5df34b721e722d468e02260f"),
"mark" : "944c1698dc62c1817cc02c68207c47bf85dfc7e830839d2ab7267899bb04ada9",
"trx_id" : "0e65b2b921019604b7928fdea11fe4e02e10550fe50fe767cbb84043b245e5ee",
"owner" : "bcskillsurou",
"contract" : "eosio.token",
"block_time" : ISODate("2019-12-13T08:27:30.000Z"),
"block_timestamp" : NumberLong(1576225650000),
"createdAt" : ISODate("2019-12-13T08:27:30.028Z")
}
如果超过一段时间,且判断mongo中块高度增长正常,且超过前面记下的块高度一段距离(以防意外的话,就是超过当前最新区块与不可逆块的差)【防止mongo同步问题】,也没记录的话,就可以判定失败了。
当前页面是本站的「Google AMP」版。查看和发表评论请点击:完整版 »