Fix for irrelevant signature included issue
This commit is contained in:
parent
4d426e1f5a
commit
a05810225a
1 changed files with 12 additions and 86 deletions
|
|
@ -2158,77 +2158,15 @@ public:
|
|||
|
||||
signed_transaction sign_transaction(signed_transaction tx, bool broadcast = false)
|
||||
{
|
||||
flat_set<account_id_type> req_active_approvals;
|
||||
flat_set<account_id_type> req_owner_approvals;
|
||||
vector<authority> other_auths;
|
||||
|
||||
tx.get_required_authorities( req_active_approvals, req_owner_approvals, other_auths );
|
||||
|
||||
for( const auto& auth : other_auths )
|
||||
for( const auto& a : auth.account_auths )
|
||||
req_active_approvals.insert(a.first);
|
||||
|
||||
// std::merge lets us de-duplicate account_id's that occur in both
|
||||
// sets, and dump them into a vector (as required by remote_db api)
|
||||
// at the same time
|
||||
vector<account_id_type> v_approving_account_ids;
|
||||
std::merge(req_active_approvals.begin(), req_active_approvals.end(),
|
||||
req_owner_approvals.begin() , req_owner_approvals.end(),
|
||||
std::back_inserter(v_approving_account_ids));
|
||||
|
||||
/// TODO: fetch the accounts specified via other_auths as well.
|
||||
|
||||
vector< optional<account_object> > approving_account_objects =
|
||||
_remote_db->get_accounts( v_approving_account_ids );
|
||||
|
||||
/// TODO: recursively check one layer deeper in the authority tree for keys
|
||||
|
||||
FC_ASSERT( approving_account_objects.size() == v_approving_account_ids.size() );
|
||||
|
||||
flat_map<account_id_type, account_object*> approving_account_lut;
|
||||
size_t i = 0;
|
||||
for( optional<account_object>& approving_acct : approving_account_objects )
|
||||
{
|
||||
if( !approving_acct.valid() )
|
||||
{
|
||||
wlog( "operation_get_required_auths said approval of non-existing account ${id} was needed",
|
||||
("id", v_approving_account_ids[i]) );
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
approving_account_lut[ approving_acct->id ] = &(*approving_acct);
|
||||
i++;
|
||||
}
|
||||
|
||||
flat_set<public_key_type> approving_key_set;
|
||||
for( account_id_type& acct_id : req_active_approvals )
|
||||
{
|
||||
const auto it = approving_account_lut.find( acct_id );
|
||||
if( it == approving_account_lut.end() )
|
||||
continue;
|
||||
const account_object* acct = it->second;
|
||||
vector<public_key_type> v_approving_keys = acct->active.get_keys();
|
||||
for( const public_key_type& approving_key : v_approving_keys )
|
||||
approving_key_set.insert( approving_key );
|
||||
}
|
||||
for( account_id_type& acct_id : req_owner_approvals )
|
||||
{
|
||||
const auto it = approving_account_lut.find( acct_id );
|
||||
if( it == approving_account_lut.end() )
|
||||
continue;
|
||||
const account_object* acct = it->second;
|
||||
vector<public_key_type> v_approving_keys = acct->owner.get_keys();
|
||||
for( const public_key_type& approving_key : v_approving_keys )
|
||||
approving_key_set.insert( approving_key );
|
||||
}
|
||||
for( const authority& a : other_auths )
|
||||
{
|
||||
for( const auto& k : a.key_auths )
|
||||
approving_key_set.insert( k.first );
|
||||
}
|
||||
set<public_key_type> pks = _remote_db->get_potential_signatures(tx);
|
||||
flat_set<public_key_type> owned_keys;
|
||||
owned_keys.reserve(pks.size());
|
||||
std::copy_if(pks.begin(), pks.end(), std::inserter(owned_keys, owned_keys.end()),
|
||||
[this](const public_key_type &pk) { return _keys.find(pk) != _keys.end(); });
|
||||
set<public_key_type> approving_key_set = _remote_db->get_required_signatures(tx, owned_keys);
|
||||
|
||||
auto dyn_props = get_dynamic_global_properties();
|
||||
tx.set_reference_block( dyn_props.head_block_id );
|
||||
tx.set_reference_block(dyn_props.head_block_id);
|
||||
|
||||
// first, some bookkeeping, expire old items from _recently_generated_transactions
|
||||
// since transactions include the head block id, we just need the index for keeping transactions unique
|
||||
|
|
@ -2242,23 +2180,11 @@ public:
|
|||
uint32_t expiration_time_offset = 0;
|
||||
for (;;)
|
||||
{
|
||||
tx.set_expiration( dyn_props.time + fc::seconds(30 + expiration_time_offset) );
|
||||
tx.set_expiration(dyn_props.time + fc::seconds(30 + expiration_time_offset));
|
||||
tx.signatures.clear();
|
||||
|
||||
for( public_key_type& key : approving_key_set )
|
||||
{
|
||||
auto it = _keys.find(key);
|
||||
if( it != _keys.end() )
|
||||
{
|
||||
fc::optional<fc::ecc::private_key> privkey = wif_to_key( it->second );
|
||||
FC_ASSERT( privkey.valid(), "Malformed private key in _keys" );
|
||||
tx.sign( *privkey, _chain_id );
|
||||
}
|
||||
/// TODO: if transaction has enough signatures to be "valid" don't add any more,
|
||||
/// there are cases where the wallet may have more keys than strictly necessary and
|
||||
/// the transaction will be rejected if the transaction validates without requiring
|
||||
/// all signatures provided
|
||||
}
|
||||
for (const public_key_type &key : approving_key_set)
|
||||
tx.sign(get_private_key(key), _chain_id);
|
||||
|
||||
graphene::chain::transaction_id_type this_transaction_id = tx.id();
|
||||
auto iter = _recently_generated_transactions.find(this_transaction_id);
|
||||
|
|
@ -2280,11 +2206,11 @@ public:
|
|||
{
|
||||
try
|
||||
{
|
||||
_remote_net_broadcast->broadcast_transaction( tx );
|
||||
_remote_net_broadcast->broadcast_transaction(tx);
|
||||
}
|
||||
catch (const fc::exception& e)
|
||||
{
|
||||
elog("Caught exception while broadcasting tx ${id}: ${e}", ("id", tx.id().str())("e", e.to_detail_string()) );
|
||||
elog("Caught exception while broadcasting tx ${id}: ${e}", ("id", tx.id().str())("e", e.to_detail_string()));
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue