The hitchhiker's guide to hard fork testing

in hive-139531 •  4 days ago  (edited)

image.png

Hello everyone,

Recently our witness has reached out to other communities to Steem with encouragement to help us test the SMT hardfork.

As you may know, the SMT hardfork is the biggest fork on Steem yet, and includes a lot of complexity and moving parts. Thus, there is a near infinite number of new actions that can be made, which in turn can result in bugs.

So far, I've been able to discover 3 chain-breaking bugs on the testnet, 2 of which has been fixed by the steemit team and one by our team.

With the importance of this fork, and the potential severity of bugs that unlike the previous hardforks could result in chain-halts at relatively random points in time (not just in the first week after the fork), we believe there is a strong need for a lot more people to participate in testing.

We've been very happy with the positive response from devs in the cn communities in particular, who have said they would like to help test the fork. However, we realized that there's no real guide to explain how to do it, or at least how I've done it.

So instead of writing long paragraphs to each one of them, I figured I would write a guide and share it to the whole community in the hopes that others may look to do the same

We absolutely need way more testers than we currently have

Step 1: Getting testnet tokens on your account

On the official testnet, all of the main net transactions are mirrored, so you already have an account and can use your own. I would recommend not using your main account anyways because most of the testing involves an active key and you don't want to slip and push your active key somewhere public by mistake.

On a side note, if you can't log in and reset your keys recently you may need to use your previous keys. the accounts are created from last october, so if you changed your keys in that timespan you need to use the keys that worked back in october.

Then you need actual testnet tokens, on the testnet STEEM tokens are called TESTS and SBD tokens are called TBD. Currently the best way to get tokens is to either ask steemit inc or use my testnet faucet: https://faucet.downvotecontrol.com/ the faucet will give you 50 TESTS and 50 TBD per query. It's open source if you want to draw some inspiration from it, although it's pretty standard stuff : https://github.com/drov0/steem-testnet-faucet.

Keep in mind that it may not work at times because I lag behind a bit to update it when the testnet restart so don't hesitate to ping me on discord : Howo#5362

Okay so you asked for some tokens and the faucet tells you you got some, how can you check ? Head on over to the steemd dedicated to the testnet:

https://testnet.steemd.com

This is also where you can (most of the time) check if the network is down or not, if it's downt he page won't load or will say "head block age is x hours old" meaning the chain stopped.

Step 2: Find out how you want to test things

I like to test things using steem-js for several reasons:

  • It's relatively easy
  • It's what most end users (devs) will be using so that way I can test the whole stack. (for hf21 I noticed a bug in the lib that was not present in steem core for instance).
  • It's pretty much the only lib that is regularly updated by steemit inc

But you are a bit "far" (in terms of abstraction) from the actual steem core, so sometimes you will be stuck because of some limitations from steem-js. For these reasons it's sometimes better to use the cli wallet.

it's advantages is that it's very close to steem core, it basically directly uses code from steem core, if something is not in the cli-wallet, it's most likely not in steem core. it also means that it will always be the most up-to-date thing you can get to interact to steem.

Disadvantage is that it's a cli (aka a command line tool), so it's not great to work with it for scripts and other things, and I find it less intuitive than working on js.

There are other ways like python scripts or unit tests, but I won't cover those here.

Step 3: Find out what you want to test

There are a lot of changes included in the smt (or any) hard fork, so how can you tell what to test ?

Big question, if the hard fork already has a release candidate you should head on over to steem's github and look for the release notes : https://github.com/steemit/steem/releases

Here's what we are looking for, taking it from hard fork 21 release notes

First of all all of the new operations. It's cucial to test those, then read through the changes and see what other operations may be affected and start thinking of edge cases.

Found an operation to test ? Great.

Step 4: Get to know your operation on a personal level

This is where things get a bit trickier, either you know c++ or you don't. Steem core is written in c++ and it's heavily templated so it's not exactly your average c++ either.

If you know c++

First of all, find out on which branch the testnet is running, could be master but could be another one. You want to review the code that is currently running. Right now the branch is 20200203-testnet

Then compile the thing, you can use the github readme page or my guide. It's useful because your IDE will be better at finding out references, for instance I use clion, and with the ctrl+b shortcut I can get the definition of functions or classes, it's extremely useful.

Now there are three places where you want to search for your operation and read through. I'll use as example the transfer operation:

first the operation definitions, this is where you have the input, auth requirements (owner/posting/active/memo) and validation definition. https://github.com/steemit/steem/blob/master/libraries/protocol/include/steem/protocol/steem_operations.hpp#L265

In the inputs, take note of the variable type, it's what is often used as min/max (if an id is an uint32 you know that the max id is 4294967295).

If you use a good IDE, the validate function should lead you to...

The stateless verification:
https://github.com/steemit/steem/blob/master/libraries/protocol/steem_operations.cpp#L251

Stateless basically means in a vaccum, it checks if your parameters are correct without testing it against the db, so you have stuff like are you transferring liquid tokens, is the sender a valid steem account (but doesn't check if the account exists) etc.

Once that step is done, head on over to the application, this is where the real deal happens, You'll find the state-full validation and the application of the operation: https://github.com/steemit/steem/blob/master/libraries/chain/steem_evaluator.cpp#L1222
This is where the actual tokens will be transferred basically.

Once you have red through this, try to think of flaws, is everything checked ? How can you break this ? Is something done inefficiently ? Reviewing the code should be a vital part of testing because it allows you to aim for something instead of blindly testing use cases.

If you don't know c++

Now is the time ! Jokes aside, I encourage you to read at least the stateless verification as it's usually straightforward and will help you direct your testing. But you will have to test a bit blindly by looking at the inputs and the operation and thinking of how to break it.

You will also struggle more to understand some stuff because a lot of logic is not documented and just in the code.

Step 5: Actually testing your operation

I will now be doing examples using steem-js because that's how I like to do things, but feel free to do it your way :)

First of all you need to config steem-js to be in testnet mode and give it a chain id.

a chain id is basically what differentiates a steem network from another fork. Usually the chain id is communicated by steemit, the current one is 98b69bd7cbe4d27864e2f06d9f74ba50aed0b7f511436ef9c7b80f36f3ff5859

So configure steem-js like so:

var steem = require('steem');
steem.api.setOptions({url: 'https://testnet.steemitdev.com', useAppbaseApi :  true, address_prefix : 'TST', 'chain_id' : '98b69bd7cbe4d27864e2f06d9f74ba50aed0b7f511436ef9c7b80f36f3ff5859'});

There are few chances that your operation will have a dedicated steem-js helper especially in the beginning so you have to build your own operation. Here's an example for the create_smt operation:

const tx = {
        'operations': [[
            'smt_create', {
                'control_account': username,
                'symbol': {'nai':nai.nai,'precision':0},
                'smt_creation_fee': {'amount':'1000','precision':3,'nai':'@@000000013'},
                'precision': 3,
            }]]
    };

Once you have your trasaction (it's an array of operations), you can plug it into broadcast along with your key:

steem.broadcast.send(tx, "Your key here",  function (err, result) {
            console.log(err, result)
});

And see the results for yourself !

You can find an example of my tests for that operation along with more example code here

Here are some tips for testing, did your operation work ? What id you do it 10 000 times ? What if you put the maximum values for inputs ? What if you put an account that doesn't exists ? Try to think outside the box ;)

Conclusion

And there you have it, folks there are more nuances to it obviously but this should already help you a ton, and if the testnet is down or if you want to do testing on your own environement, check out how to do so on my guide to setup a local testnet


vote witness.png

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!
Sort Order:  

Users and stakeholders always complain about a lack of testing prior to hardforks. @steempress witness is actually doing something about it.

If you appreciate our contributions as a technical witness, do consider voting for @steempress through the witness page or through steemconnect here

^ yes

Very informative and helpful post thanks for sharing

Very informative guide. Please continue to sharing such a helpful material with us. Thanks

Congratulations @howo!
Your post was mentioned in the Steem Hit Parade in the following category:

  • Pending payout - Ranked 1 with $ 95,4

Congratulations @howo! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :

Your post got the highest payout of the day

You can view your badges on your Steem Board and compare to others on the Steem Ranking
If you no longer want to receive notifications, reply to this comment with the word STOP

Do not miss the last post from @steemitboard:

Valentine's day challenge - Give a badge to your beloved!
Vote for @Steemitboard as a witness to get one more award and increased upvotes!

Thanks for the info