SteemPress testing results of HF21

View this thread on: d.buzz | hive.blog | peakd.com | ecency.com
·@steempress·
0.000 HBD
SteemPress testing results of HF21
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](https://steemitwallet.com/~witnesses). 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.

![Fork test.png](https://cdn.steemitimages.com/DQmTP7PwtkNjbp7TEc5SRGYvW7qtBzn3JG8cffG9NSYP17o/Fork%20test.png)
_HF21 was [released and tagged last week](https://steemit.com/hf21/@steemitblog/hf21-release-tagged), 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](https://steemit.com/steem/@steemitblog/hf21-sps-and-eip-explained) 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 the`memo_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/446

Thanks 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:

![](https://i.imgur.com/Aje0tEw.png)

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.
<a href="https://beta.steemconnect.com/sign/account-witness-vote?witness=steempress&approve=1">
![vote witness.png](https://cdn.steemitimages.com/DQmUx8rMsaHTqs5YzJMHj16NyTXGkrDo28fqeLXotMSEKXc/vote%20witness.png)</a>

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](https://steemitwallet.com/~witnesses) or through steemconnect [here](https://beta.steemconnect.com/sign/account-witness-vote?witness=steempress&approve=1).
👍 , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,