SteemPress testing results of HF21

in testing •  5 years ago 

 Hello Steemians! This post relates to our witness and the tests we have carried out in preparation for hardfork 21 (HF21). As most of you hopefully know, @steempress operates a witness and is currently rank #24 on the witness list. With that comes the responsibility to participate in testing and contributing to updating the blockchain such as a hardfork. If you follow this account primarily for updates on our plugin and are not interested in a highly technical update, this post may not be for you. However, if you are interested in the contents of the next hardfork, in the technical details for it, or overall want to see what else we do as a witness, then please read on.
HF21 was released and tagged last week, meaning it's now or never to test everything. You can find the whole release notes here: https://github.com/steemit/steem/releases/tag/v0.21.0.HF21 is scheduled for Tue, 27 August 2019 15:00:00 UTC (a date that may be subject to change depending on the number of found bugs or issues in the proposal). As it is crucial to test things thoroughly in advance before such a release, we figured that we would show some of our own findings and share with you the work that we have done testing HF21so far.There are four new operations, the first three are linked to the new proposal system that we encourage anyone to check out here who haven't already.

  • create_proposal
  • update_proposal_votes
  • remove_proposal
  • account_update2

In order to test those, we went the stem-js route because it means we can test the whole pipeline from lib to rpc api. Since that's also how most developers will interact with the chain, it makes sense to test the libraries as well as the chain.

Account_update2

This is pretty much a mirror of the account_update operation, with the only difference being that it doesn't need the active_key. This is a great change because it means that apps can now offer trivial yet useful options such as changing a user's profile picture inside the app without needing their Active key.Account_update2 has the same parameters as account_update, but we weren't sure what the rpc operation name is since there isn't another operation that ends with a number. account_update2 is the function name that was widely used everywhere in the c++ code, but it could be account_update_2 depending on how they interpret snake_case. So we went with account_update2 which seemed like the right choice.Basically, since the parameters are the same, one should be able to take a working test case from account_update and just update it slightly to take a posting key instead :

const wif = steem.auth.toWif(username, password, 'active');

let ops = [];

let account = await steem.api.callAsync('condenser_api.get_accounts', [[username]]);
account = account[0];


ops.push([ 'account_update', {
   'account': username,
   memo_key : account.memo_key,
   posting_key : account.posting.key_auths[0][0],
   active_key : account.active.key_auths[0][0],
   owner_key : account.owner.key_auths[0][0],
   'json_metadata': "",
   "posting_json_metadata" : ""
}]);


let tx = {operations: ops, extensions: []};

const result = await broadcast(tx, wif);

assert(result.error);

For reference broadcast looks like this :

function broadcast(tx, wif)
{
   return new Promise(resolve => {
       steem.broadcast.send(tx, {wif}, async function (err) {
           if (!err) {
               return resolve({error : false, err})
           } else {
               return resolve({error : true , err})
           }
       });
   });
}

Which works perfectly.But if we try to do the same with account_update2

const wif = steem.auth.toWif(username, password, 'posting');

let ops = [];

let account = await steem.api.callAsync('condenser_api.get_accounts', [[username]]);
account = account[0];


ops.push([ 'account_update2', {
   'account': username,
   memo_key : account.memo_key,
   posting_key : account.posting.key_auths[0][0],
   active_key : account.active.key_auths[0][0],
   owner_key : account.owner.key_auths[0][0],
   'json_metadata': "",
   "posting_json_metadata" : ""
}]);


let tx = {operations: ops, extensions: []};

const result = await broadcast(tx, wif);
assert(result.error);

We get Assert Exception:itr != to_full_tag.end(): Invalid operation name: account_update2 which is odd, because if we remove the parameters memo_key, posting_key, active_key, owner_key it'll tell us that it needs those parameters (which is also odd since the documentation states that they are optional). This means that it does recognizes the operation account_update2 and it's needed parameters but where it somehow won't work if we include all.

After some back and forth with @justinw and @vanderberg, we found that the current testnet was deployed before account_update2 was added to condenser_api. Which was causing the bug.

We then realized that there was an issue with steem-js, namely that it would make the parameter memo_key mandatory. I assume that since account_update2 has almost the same parameters as account_update, the same validation was used.The issue is that if you include thememo_key parameter, then account_update2 requires the active key to execute (since you're trying to change your memo key). Which defeats the whole purpose of account_update2, an account_update with the posting key.So since this is an actual problem, we've opened an issue here: https://github.com/steemit/steem-js/issues/446Thanks to @vanderberg a fix was found quickly and we've opened a pull request to fix the problem:https://github.com/steemit/steem-js/pull/447

create_proposal

As the name suggests, this operation allows you to create a proposal to the SPS. It's parameters are:

creator: creator of the proposal
- receiver: receiver of the daily sbd
- start_dat : starting date of the proposal
- end_date: end date of the proposal
- daily_pay: daily pay (in sbd)
- subject: basically a title
- permlink: permlink to an existing post describing your proposal

These parameters are pretty straightforward. We managed to create a proposal very quickly meaning that the base case works. We then checked the blockchain code to see what kind of verifications had already been done to know if some things were not tested yet. Those validations would be located in /libraries/chain/sps_evaluator.cpp. Then there's validation regarding the types themselves during casting, for instance, dates are verified by the time_point_sec.So after reading a bit here's the tests regarding the parameters that are in the blockchain:

  • end date must be in the future
  • proposal creator has to exist
  • proposals receiver has to exist
  • permlink must lead to existing post exist

We went on to test the following cases to give you an idea:

create_proposal normal
create_proposal ends before today
create_proposal negative pay
Proposal permlink doesnt exists
Proposal daily pay overly large number
Proposal daily pay overly large title
Proposal start date does not exist (start date was set in -2018)
datetime underflow  (start date is in 1501)
Proposal start date is far in the future (proposal payout is between 2040 and 2041)
Proposal duration is less than a day
Proposal duration is less than an hour

And the chain handled everything very well!The only part we found questionable was the lack of any check to prevent a proposal from being entered that would end before a day has passed. This, however, is not a big problem in itself as it would hurt the user and not the chain and could be handled by and front ends through which most users would submit a proposal. It is worth noting though.

update_proposal_votes

There are way fewer parameters to this call and thus there is less to test, it works very much like witness voting.the parameters are the following:

voter: Your username 
proposals_ids: ids of the proposals you want to vote for (array)
approve: add or remove votes for the proposals_ids array (true or false)

And there were no problems as far as we could tell. Here is nevertheless a list of the tests that we conducted:

proposal vote
remove votes on one
vote with no proposal_id
vote nonexistent proposal id
vote with an id that overflows
vote on a list of existing and nonexisting proposal IDs

Side note on the total_votes value of the find_proposals operation.One might want to test the result of voting with the find_proposals call.Here's an example from the call:Even if you vote for a proposal, the total_votes field will stay at 0. This is because vote calculations are not executed instantly but instead calculated during the "maintenance time" of the blockchain. For those who don't know, this is a time where the chain executes computationally intensive tasks and happens roughly once every hour.As @blocktrades puts it: "think of it [the vote operation] like mailing in a vote then waiting for the election time for it to count"

Remove proposal

Since this operation only serves to remove a proposal, there are only two parameters, and thus not much to test. These two parameters are:

  proposal_owner // self explanatory
  proposal_ids // array of proposals ids

our test cases were as follow :

remove proposal
remove proposal that has already been removed
remove a proposal that we do not own
remove several proposals that we own
remove several proposals including one we don't own
remove a proposal that doesn't exist

In the end, we found no problems here, except perhaps the fact that one can remove proposals that never existed or that were already removed.While this has no significant consequences, it is still a useless transaction for the chain.

SPS beneficiaries

One new feature in HF is the ability to fund the SPS through beneficiaries. However, since the SPS only operates with SBD, there is now a new logic that will automatically convert the STEEM and SP to SBD tha can be used for the SPS.So we tried this out by creating a post with 100% beneficiaries to the SPS: The post went through without any problems and payout happened as expected with the SPS also converting everything properly.

Conclusion

In conclusion, the only "real" problem we found did not come from the blockchain but rather the tools above it. Which is a really good thing!
If you are interested in seeing our testsuite, here's a gist with all of it: https://gist.github.com/drov0/efb8f0a134851030ac2b434520ba333b. Note that mocha is needed in order to run it.We are continuously performing more tests of HF21 ahead of its release and will let you know if find anything else that is significant.

We see it as crucial that top witnesses participate in thoroughly testing new hard fork proposals and to also allow the community and stakeholders to know what has been tested in order to minimize potential issues following a fork. If you appreciate our contributions as a technical witness, do consider voting for @steempress through the witness page or through steemconnect here

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!