Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge release branch to master branch for 4.0 release #2093

Merged
merged 673 commits into from
Jun 30, 2020
Merged

Merge release branch to master branch for 4.0 release #2093

merged 673 commits into from
Jun 30, 2020

Conversation

abitmore
Copy link
Member

@abitmore abitmore commented Jan 29, 2020

For final review and fix.

Note: not all issues found in review have to be fixed in this release, some of them could be addressed in future releases but don't forget to track them.

docker/default_config.ini Outdated Show resolved Hide resolved
docker/default_config.ini Outdated Show resolved Hide resolved
libraries/app/api.cpp Show resolved Hide resolved
libraries/app/api.cpp Outdated Show resolved Hide resolved
libraries/app/include/graphene/app/api.hpp Outdated Show resolved Hide resolved
libraries/app/include/graphene/app/api.hpp Outdated Show resolved Hide resolved
libraries/app/include/graphene/app/api.hpp Outdated Show resolved Hide resolved
libraries/chain/committee_member_evaluator.cpp Outdated Show resolved Hide resolved
adjust_balance( obj.transfer.from, amount );
// notify related parties
htlc_refund_operation vop( obj.id, obj.transfer.from, obj.transfer.to, amount,
obj.conditions.hash_lock.preimage_hash, obj.conditions.hash_lock.preimage_size );
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simply adding fields to the vop does not automatically notify new parties unless also added code to get_impacted_account_visitor::operator()( const htlc_refund_operation& op ) in db_notify.cpp. However, if not implemented carefully, account history (2.9.x) numbering would be affected which would break 3rd client apps who rely on consistent numbering. The careful approach is similar to what's done in #1629.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought I added them to _impacted. Will do. I will also add the boolean based on HF date to prevent account history numbering issues.

Copy link
Contributor

@jmjatlanta jmjatlanta Mar 26, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Upon further research,

  1. I didn't write this, so that explains why I didn't add the necessary code :-)
  2. the original ticket mentions it not needing a hard fork since the virtual op does not involve consensus. Therefore we have an issue of when should we turn on this feature. My suggestion would be to make it "hardfork-like" and wrap it with hardfork protections tied to BSIP 64.

Your thoughts please @abitmore

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the link to the original ticket. Just realized that what I wrote in the reviews are actually new features. So, I think we will only work on this if we have enough time.

Yes, my thought was to make it hardfork-like. For implementation, I'd like to refactor Nathan's code, pass in a time rather than several booleans, write different logic for different operations.

htlc_redeemed_operation virt_op( htlc_obj->id, htlc_obj->transfer.from, htlc_obj->transfer.to,
o.redeemer, asset(htlc_obj->transfer.amount, htlc_obj->transfer.asset_id ) );
htlc_redeemed_operation virt_op( htlc_obj->id, htlc_obj->transfer.from, htlc_obj->transfer.to, o.redeemer,
amount, htlc_obj->conditions.hash_lock.preimage_hash, htlc_obj->conditions.hash_lock.preimage_size );
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the HTLC was redeemed by to, she won't get notified by the virtual htlc_redeemed_operation, thus it's still inconvenient for her since the new added fields are not in htlc_redeem_operation. In addition, the redeemer won't get notified with the virtual operation. IMHO it's better to simply notify all parties in get_impacted_account_visitor::operator()( const htlc_redeemed_operation& op ). Need to take care of account history numbering if to take this approach.

visit() { return true; }
template<typename Op>
std::enable_if_t<TL::contains<BSIP_40_ops, Op>(), bool>
visit() { return HARDFORK_BSIP_40_PASSED(now); }
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's better to put the code related to bsip40 in a new bsip40-hf-visitor class/struct which is derived from a generic hf-visitor class/struct.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hardfork_visitor is quite similar to the get_impacted_account_visitor -- it should work for all operation types and should tell you something about that operation in a reasonably polymorphic fashion. Thus it needs to deal with all operation types within a single struct; it can't reasonably be split over multiple structs or files.

It looks like the BSIP40 code is a special case here because it's the only case that existed at the time it was written that wasn't trivially true. Over time, all new operations will be added to this so that a generic operation can always be inspected to see if it's forked in yet or not, so the BSIP40 handling is not really out of place here.

Copy link
Member Author

@abitmore abitmore left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@oxarbitrage please check if have time. Thanks.

Update: I'm working on it.
Update: done with #2134.

libraries/plugins/custom_operations/custom_evaluators.cpp Outdated Show resolved Hide resolved
libraries/plugins/custom_operations/custom_evaluators.cpp Outdated Show resolved Hide resolved
libraries/plugins/custom_operations/custom_evaluators.cpp Outdated Show resolved Hide resolved
FC_REFLECT(graphene::protocol::custom_authority_update_operation,
(fee)(account)(authority_to_update)(new_enabled)(new_valid_from)
(new_valid_to)(new_auth)(restrictions_to_remove)(restrictions_to_add)(extensions))
FC_REFLECT(graphene::protocol::custom_authority_delete_operation, (fee)(account)(authority_to_delete)(extensions))
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION is missing in this file. See #1768 and #1818.
Need to check other related files as well.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added: bc5c34b

/* 16 */ withdraw_permission_id_type, \
/* 17 */ vesting_balance_id_type, \
/* 18 */ worker_id_type, \
/* 19 */ balance_id_type, \
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The list was initially generated when HTLC is not implemented, so the data types used in HTLC-related operations E.G. htlc_id_type and htlc_hash are not in the list. I haven't fully reviewed the code so far, so I'm not sure how users could create custom active authorities (CAA) for the HTLC-related operations. Just think that the CAA feature should be ease to expand. Will update when have more info.

Copy link
Member Author

@abitmore abitmore Mar 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The *_id_types are listed here mainly for the convenience to compare 2 containers. For individual id types, it's possible to create restrictions with func_attr which will recurse into the object_id struct and restrict the instance field directly.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was wrong. object_id::instance is not reflected, thus we're unable to recurse into it with func_attr. It means we need to add the missing types in this type list. Updated the previous comment.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Best if we can have code to check whether there is a type missing, or a field that can't define restrictions for. For the fields that aren't supported, we need to document them. In my old implementation (https://github.com/bitshares/bitshares-core/pull/1362/files#diff-e9075b54e174b51fa26c8db6f535b8f2R440) I didn't support all types.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Best if we can have code to check whether there is a type missing, or a field that can't define restrictions for. For the fields that aren't supported, we need to document them. In my old implementation (https://github.com/bitshares/bitshares-core/pull/1362/files#diff-e9075b54e174b51fa26c8db6f535b8f2R440) I didn't support all types.

See 3cd47d1

The list was initially generated when HTLC is not implemented, so the data types used in HTLC-related operations E.G. htlc_id_type and htlc_hash are not in the list. I haven't fully reviewed the code so far, so I'm not sure how users could create custom active authorities (CAA) for the HTLC-related operations. Just think that the CAA feature should be ease to expand. Will update when have more info.

See b957a22

namespace graphene { namespace protocol {
using result_type = object_restriction_predicate<operation>;

result_type get_restriction_predicate_list_1(size_t idx, vector<restriction> rs) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably better if make a template file and generate these source files with a script or cmake configuration.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See 738ac6f

if (typelist::contains<operation_list_8::list, Op>())
return get_restriction_predicate_list_8(typelist::index_of<operation_list_8::list, Op>(), std::move(rs));
if (typelist::contains<operation_list_9::list, Op>())
return get_restriction_predicate_list_9(typelist::index_of<operation_list_9::list, Op>(), std::move(rs));
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally I don't like the long list of ifs, but perhaps it's just me. We can improve it in the future anyway.

For reference, in my first (partial) implementation I tried to do it via switch-case, see https://github.com/bitshares/bitshares-core/pull/1362/files#diff-e9075b54e174b51fa26c8db6f535b8f2R507.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this list annoys me too. It's there to break up the build and keep too many template instantiations from happening in one compilation unit. Unfortunately, it's annoying to get rid of because it's so arbitrary. You could replace it with some kind of mapping or jump table of list-type-to-callable but it's not clear to me that it would be an improvement.

const auto& to_num(const I& i) { return i; }
template<typename I>
const auto& to_num(const fc::safe<I>& i) { return i.value; }
inline auto to_num(const fc::time_point_sec& t) { return t.sec_since_epoch(); }
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might deal with unsigned_int similarly here. Actually, IMHO unsigned_int should be treated as integral.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See 3cd47d1

// Simple comparison, same types
constexpr static bool valid = true;
constexpr int8_t operator()(const Field& f, const Argument& a) const {
return f<a? -1 : (f>a? 1 : 0);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's possible that operator > is not implemented in some data types. I guess it's better to use a<f here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done: 71de24b

/* 10 */ committee_member_id_type, \
/* 11 */ witness_id_type, \
/* 12 */ limit_order_id_type, \
/* 13 */ call_order_id_type, \
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This ID is not used in consensus.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See b957a22

/* 6 */ fc::sha256, \
/* 7 */ account_id_type, \
/* 8 */ asset_id_type, \
/* 9 */ force_settlement_id_type, \
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This ID is not used in consensus, but only used in virtual operation(s).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See b957a22

/* 11 */ witness_id_type, \
/* 12 */ limit_order_id_type, \
/* 13 */ call_order_id_type, \
/* 14 */ custom_id_type, \
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This ID is not used in consensus.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See b957a22

/* 15 */ proposal_id_type, \
/* 16 */ withdraw_permission_id_type, \
/* 17 */ vesting_balance_id_type, \
/* 18 */ worker_id_type, \
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This ID is not used in consensus.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See b957a22

/* 16 */ withdraw_permission_id_type, \
/* 17 */ vesting_balance_id_type, \
/* 18 */ worker_id_type, \
/* 19 */ balance_id_type, \
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned above, htlc_id_type is missing, as well as custom_authority_id_type. Perhaps it's good to exclude custom_authority_*_operation though.

Copy link
Contributor

@nathanielhourt nathanielhourt Jun 18, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See b957a22 and 56d7ef6

libraries/protocol/custom_authorities/sliced_lists.hxx Outdated Show resolved Hide resolved
::add_list<typelist::slice<operation::list, 47, 51>>
::add<htlc_extend_operation> // 52
::finalize>;
using operation_list_9 = static_variant<typelist::slice<operation::list, 54>>;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do not need to support CAA for these operations:

  • account_transfer_operation which is defined but not implemented;
  • committee_member_update_global_parameters_operation which must be done with committee-account;
  • blind_transfer_operation and transfer_from_blind_operation which must be done with temp-account;
  • asset_update_issuer_operation which requires owner permission.

BTW custom_authority_*_operations are supported here, I'm not sure if it's a good idea to support them in the first release due to their complexities.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See 56d7ef6

/* 3 */ string, \
/* 4 */ time_point_sec, \
/* 5 */ public_key_type, \
/* 6 */ fc::sha256, \
Copy link
Member Author

@abitmore abitmore Apr 1, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may need to support fc::ripemd160, fc::hash160, fc::sha1 and etc for assert_operation and HTLC operations.

Copy link
Contributor

@nathanielhourt nathanielhourt Jun 18, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See 7c66d15 and 4e81e2b

};
template<typename Field, typename Argument>
struct predicate_eq<Field, Argument, std::enable_if_t<is_container<Field> && is_integral<Argument>>> {
// Compare container size against int
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Best if support container size inequality comparison as well (E.G. restrict that a container's size is greater or less than X). That's why my implementation had a member modifier field (https://github.com/bitshares/bitshares-core/pull/1362/files#diff-33c4d93495a6f66f876600be88117390R35).

By the way, best if support comparison between a static_variant and an int, which implies compare(static_variant::which(), int).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See 4e81e2b

template<typename, typename = void>
struct is_container_impl : std::false_type {};
template<typename T>
struct is_container_impl<T, make_void<typename T::value_type, decltype(declval<T>().size())>> : std::true_type {};
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO a vector(char) should be treated as a string but not a container.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See 4e81e2b

template<typename Container, typename Element>
struct predicate_in<Container, flat_set<Element>,
std::enable_if_t<is_container<Container> &&
comparable_types<typename Container::value_type, Element>>> {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The flat_map type used in graphene::authorities is not supported. Perhaps implement something similar to variant_assertion.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would be interesting, but I anticipate it'll be a fairly niche use case. I'm calling it future work. :P

@abitmore abitmore mentioned this pull request Apr 6, 2020
nathanielhourt added a commit to nathanielhourt/bitshares-2 that referenced this pull request Jun 18, 2020
See bitshares#2093 (comment)

Add a cmake template file for the list_#.cpp files and autogenerate them
from the template rather than having 12 almost identical copies of a file
@abitmore abitmore marked this pull request as ready for review June 28, 2020 23:41
@abitmore abitmore merged commit c9e2bf4 into master Jun 30, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants