Running everyday dapp when Ethereum is under pressure

makoto_inoue
BlockParty
Published in
11 min readJun 25, 2017
Traffic increase observed during Status.im ICO, a tweet from MyEtherWallet

Intro

The latest Ether price increase and massive traffic during big ICOs are challenging the capacity of Ethereum.

In this blog post, I will share the experience of running every day dapp (which is a rare unicorn at this moment) under such a harsh circumstances.

It’s quite a long post so go grab coffee, or save it offline to read on train/underground.

Stories so far

I have been working on an event management dapp called “BlockParty”. You pay a small deposit when you register. You lose your deposit if you do not turn up. You will get your deposit back + we split the deposit of whom did not turn up. Simple!

So far I have used the Dapp in the two occasions, first at pre conf dinner at DevCon2 in Shanghai and then post conf lunch at EdCon in Paris. To find out more, read and watch the followings.

CodeUp

I have been organising a monthly Ethereum coding group called “London Ethereum Codeup”. Even though I created BlockParty to prevent no shows there, I have never used it for real because we never exceeded more than 20 sign ups which is the capacity of our office room.

However, as the price of Ether goes up, the interest to our humble study group also went up and the last meetup in May was the first time that there was a person in the waiting list who could not come. The Ether price even got higher in June and we had about 8 people in the waiting list a week before the meetup day. Now is the right time to try out BlockParty.

Our last Codeup, 14 turn ups which was the record

Estimating the gas cost

When I organised the last two events, the price of the Ether was £10(~$13). The entire gas cost of deploying, registering, marking attendees as “attended”, starting payback, then withdrawing Ether cost only a few pounds so I didn’t have to worry about the gas cost. Just before deploying the contract in the beginning of June, Ether was somewhere around £300(~$400) so the simple math indicates that it will cost around £30 which is not cheap at all. I need to find out a way to optimise the cost, which turned out not so difficult.

The total gas cost running the first blockparty at DevCon2 (1ETH = £10)

I use Truffle framework to develop my Dapp. Truffle is a great framework to simplify the development and deployment workflow with sensible default configuration value. The problem is that the “sensible” gas cost never stays the same. According to the doc, it sets the default gas price as 100 gwei (= 100 shannon = 0.0000001 ether). I wrote a quick simulation test to calculate how much each function will cost and I ran it against testrpc

When I discussed the problem with Nick Johnson of ENS, he quickly pointed out that 100 gwei is a lot higher than the average gas cost of 20 gwei. Changing the gas cost shows that the total is £14, which is still a bit expensive for organising a meetup.

He further told me that now around 10% of miners accept 2gwei, it just takes longer for the transaction to get mined. Setting it to 2gwei indicates that now the total is £1.42, which is quite similar to the price I paid in the previous deploy. This is not bad at all.

Deploying the contract

I haven’t deployed to mainnet for almost 4 months so my geth node was massively out of sync. When I tried to resync the node, I ran out of my disk space so had to purge the db and restart with --light mode, which saved massive 50GB of disk space. Why I haven't done that earlier!

geth removedb
geth --light

When I deployed in the morning, I got the following error.

$truffle migrate --network mainnetError: Contract transaction couldn’t be found after 50 blocks

I tried to change the default timeout of Truffle and retry, but couldn’t figure out where I change the configuration. That’s the problem of depending too much to a framework. It suddenly becomes quite difficult to configure things the framework does not expect you to change.

However, the geth console indicates that transaction has been made, and etherscan page shows that the transaction is pending. I had to get back to my day job so I left it as is and by the time I came back home, I confirmed that the transaction was mined after 300 blocks, which is just over an hour.

So, I decided to manually update the address at Conference.json and looks working fine.

I also try to register myself using Metamask. Did you know that you can actually change the gas price?

This time it took about 30 min to get mined. It’s slow but still not too bad. Now I am ready to announce.

Sending Invitation

Because people have already registered in meetup.com page and this is the first trial, I made the BlockParty registration as optional and sent the following email into the registered members 2 days before the meetup.

As an experiment for the future codeup reservation, I deployed an experimental contract on both mainnet and testnet. If you are definitely coming to the meetup, please register at the following (please select the right network) as a brave guinea pig.

http://bit.ly/blckprtycodeup21

Please read the following notes carefully before you participate.

- This code may contain bugs. In the case of unexpected deposit loss or theft, we will try our best to manually rescue the situation but there is no guarantee that you get your Ether back.

- Please be reminded that this is an experiment and does NOT replace meetup.com booking yet. If you don’t have the slot, I advise not to register unless you are willing to give away your deposit.

- You can register until the morning of the day. To be eligible for attendance, please come to our venue by 7pm.

- The `register` function takes about 1.6M gas and `withdraw` function about 50k gas.

- That’s equivalent of 0.0038 Ether (worth around £1) if your gas price is set to 20gwei, £0.1 if 2gwei.

- If you are using MetaMask, the default gas price is 20gwei but you can lower to 2 gwei.

If you set your gasPrice to 2gwei, it will go through but will take a long time (took about 30 min when I register).

- It may take even longer as status.im ICO is expected to happen today and Ethereum network may get congested. Be patient.

Status.im ICO

As I mentioned in the invitation, I was aware that there will be some latency in the network due to the status.io. What I did not expect was the extent of the volume.

They were going to start their crowdsale at block number 3903900 at 2pm GMT which eventually happened at 3:51pm GMT.

Around 1:30pm GMT, it was still about 700 blocks away from the start block but people were already sending transaction to the crowdsale contract and I was seeing lots of pending transactions on Etherscan. You may think stupid to send transaction before the blocktime but that was understandable to me as you never know the exact time it starts and also how long it takes for your transaction to be confirmed. ManyEthereum stats site were down during the time, so you had to guesstimate unless you connected to local node (which I did via geth but probably most non tech people wouldn’t have known how to do that).

A Japanese tweet saying etherscan being down

I tried to make a very small transaction (0.001 Ether) to their contract address to see how long it takes to get mined (then rejected because the crowdsale hasn’t started). Interestingly I could not check the transaction at all. I even contacted Infura/Metamask but they also did not find my transaction (using web3.eth.getTransaction(trx)).

I ended up sending 3 more transactions from my own node, but none of them ever reached the contract.

There was another coincidence. The actual status.im ICO start time coincided the start time to bid blockparty.eth as well. I bid right after status.io ICO started but again that never reached the ENS auction.

I later learnt how to cancel my previous transaction and bid again.

There was the side effect of status.im event after the ICO ended.

Looks like the average gasPrice was jumped from 20gwei to 50gwei. Is it because status.io team set their maximum gas price to 50gwei? Is 50gwei the new average now?

Gas price stats from Etherscan

The day of the meetup

In the morning of the meetup, there were 4 registrations to BlockParty. I was helping out one participant’s registration around 11am so that the total of 5 participants were expected before I was going to close the registration at the noon (there is on “close registration” function, so I was going to decrease the number of participants).

Because it was not compulsory, I wasn’t taking it seriously and I left the registration open until around 5pm. Then I received a message from one of the members that he decided to go to different meetup which I posted at our message board. Interestingly this person actually registered via Blockparty. This means that any people who registered gets extra Ether. Now we are in business!

I quickly went into the etherscan and I can see that there were two pending transactions. By looking into their transaction hashes, I can see that they were registering with gas price of 2 gwei. Umm, is there a way to beat these transactions? Of course! I sent setLimitOfParticipants(4) with 50 gwei which was mined in a few minutes. This is actually a race condition happening in real life (but very slowly).

During the meetup, I explained these logic and proudly tried to settle, but it kept showing errors. Oh, did I hit a bug so that no one can attend? I was red in the face trying to debug while all the participants were introducing themselves. It turned out that I was trying to call admin functions with non admin accounts.

It was a very interesting learning experience. We usually take complex logic as a blackbox and blockchain is no exception. When things are not working as expected, it gives a chance to go deep into the technology.

Here is a comment from one of our participants.

“makes me feel smart & cool” via @bubukhan

How much did it actually cost for me?

This is what I actually spent.

I spent more than double (£3.9 rather than £1.4) because of the following reasons

  • I called setLimitOfParticipants with 50gwei which I wasn’t expecting to do at the beginning. Even worse, I called the function twice by mistake.
  • Attend and Withdraw cost 30gwei because I wasn't using metamask and I did not create a UI for admin to manually adjust gas size. I think 30gwei is the default gasPrice though I couldn't find the figure in the documentation of web3 nor Truffle.

Luckily I earned 0.016 ether which was just enough to cover the admin cost.

“Throw” or “Return”

What happened to these poor pending transactions in the end? One of the transactions indicates that it was confirmed at 3am in the following morning (this means that I did not even have to limit the number of participants as none of the 3 transactions arrived by the start of the meeting).

The normal best practice of calling a function after the deadline is usually throwwhich consumes all the gas. This makes sense in the normal situation to discourage people to call functions in the unexpected way to penalise their behavior. However, in this scenario, the late registration was not really the fault of participants so it's too harsh to penalise.

Luckily, my register function had a modifier called onlyActiveOrReturn

modifier onlyActiveOrReturn {
if (ended == false) {
_;
}else{
if(!msg.sender.send(msg.value)) throw;
}
}

Instead of throwing , and burning all the gas, it just returned the deposit value by only consuming the gas it needed. In this late registration case, The participant set gasPrice to 5gwei with gasLimit of 1,000,000, actually consuming 31,000. throwwould have cost him £1.5 but it actually cost him £0.05. I was going to replace this logic with throw but probably better to keep it as is.

Moral dilemma

So what should you do if the underlying network behaves in the very unexpected manner.

In our case, two people were not be able to register even though they tried to register (not sure if they registered before noon though). Should I have rescued the victims like Coinbase did for the flash crash victim?

For the two of you who are the in the pending transactions 0x86fb99.. and 0x113f… If you actually submitted before noon (which I just have to trust you because there are no evidence) and you happen to read until this point, ping me. I will send 0.01 ETH which you were supposed to win (of course you must be the one who attended the codeup) .

0.01 = (0.05 * 6 / 5) - 0.05

There is no guarantee that I will rescue the same way in future but this is one of these scenarios Dapp developers should think about. What should you do if Ethereum network behaved in the way your smart contract did not expect?

Is Ethereum ready to run an everday dapp?

Here is the taste of running everyday dapp when Ethereum is under pressure. We sometimes see that our life goes into halt when certain services (eg: github, twitter, amazon) hits performance problem.

In case of Blockchain , one big event can impact the entire Ethereum ecosystem.

So what are the options for us?

  • Don’t use Ethereum for everyday life. It’s still too early for that.
  • Don’t do ICO. It hurts everybody.

That’s probably needed for the short term solution. However these themselves do not contribute to solve the problem.

The better alternatives are.

  • Join and contribute to the conversation of improving better ICO process = Whether you like it or not, ICO is the first killer app of Ethereum and inability to form ICO will equally hurt our ecosystem.
  • Fail fast, fail often (but fail safe) = You can spend years shoe horning your next killer dapp but you never know the quirks of running dapps in the mainnet. The mainnet works differently compared to running on testnnet or private chain. Is there a way to run your project in the mainnet for smaller scale so that you can learn a lot by failing/suffering but not with catastrophic failure?

Lastly (but not least)

I am hoping that BlockParty to be one of these fail fast, fail often but fail safe dapp which solves your every day problem. I am currently working with London Ethereum meetup group to prevent no shows of their massively popular events.

And NYC meetup seems interested, too.

Do you run any blockchain events which could potentially use BlockParty? If so, please fill in your detail in the following form so that you can be one of these brave guinea pigs when it is ready.

https://goo.gl/forms/D7puPx7COTZ0w4uU2

--

--