DAPPCON 2018: How to Be Light Client Friendly? - Tomasz Drwiega (Parity Technologies)
DappCon 2018 · July 2018 · 18:10
Tomasz Drwiega of Parity Technologies discusses light client design at DappCon 2018, addressing what makes an Ethereum client friendly to devices that cannot store the full chain. The talk covers the tradeoffs involved in syncing state efficiently, a scaling concern shared by wallets and dapps that need fast, low-resource access to on-chain data.
Speakers
Topics
From DappCon 2018, hosted by Dappcon Berlin.
Transcript
cool hello everyone my name is Thomas Topanga I'm from parity technologies and today I would like to talk light clients so light clients well what do I mean by light clients well light client this is just a node in a network but it's kind of a special kind of note so what I mean by light is light as in it has low resources usage usage so all like CPU memory storage and i/o its embeddable so you can build your own application and you don't need to run a note as a separate process but you can kind of use a library that will be a light client in
your application in your language but it's still trustless so don't confuse it with something that we is sometimes called thin clients so clients that's you just run in your browser and they are just connecting to that some kind of REST API and get the data but don't verify that that that data and all and just trust that the data provider so we are heel here still more secure than than using that in clients so why light clients as as the guy who was introducing me mentioned already like syncing a full note is really hard these days so sync time currently is you measure the same time in days so it's
not hours as it used to be like a year or a year and a half ago it's nowadays the state size is gigabytes and the entire database which contains States after every block also the blockchain data is actually tens of gigabytes right now if pruned light load on the other hands you can sync it in seconds state size is actually zero completely zero and the data bytes like the database size the entire database that we store is is in megabytes and in parity technologies we believe that light clients will be a really important part of like the future of the
centralized networks and this is kind of reflect that in our latest actions and latest releases so as you may have noticed in parity theory we have actually deprecated the parity wallet so the UI part is actually separate application right now we are focusing more on the core technology so running a full notes for this kind of like infrastructure level providers and running light knows for casual users on desktops or laptops and pretty soon I hope within a couple of months we're gonna be releasing a new solution which is a light note and the light wallets together and it's actually
called feather you can go to github you can see how it works and you can test it already there are a couple of releases as you can see here and how does it work here you can see how sort of a full node works so when we are syncing a full node we are actually fetching all the headers from the from the network then for every header we have a body that contains all the transactions that should be run and given the previews given the previous state state before block one so for instance whew it will be a Genesis state and the list of transactions we can apply those transactions to the state and get a new state after that
particular block okay then we get a block number two again list of transactions and we have another state after block number two and some of the notes namely archive notes they actually store all the states at every block that happens in each idiom but obviously as adapt developers we are usually mostly concerned with the latest state so the state after the latest block so we can for instance prune that all all states so this will lower our our database size a little bit but what we do for light clients we actually only synchronize headers so we are not running the transactions we are not producing those states at all we are just checking that
the headers are correct I mean like they are consistent and the parent hash actually matches and also headers contain like this two things that will be useful for us later because the idea is that we don't have the state ourselves we don't really have that transactions ourselves but we can ask other nodes in the network to provide us those transactions or the state but actually they also have to give us a proof that the data that they provided is correct so this is a miracle proof that we can verify by checking the state routes that we actually store obviously if we would just think that all the headers it would still be like a little bit too big so I think all the
headers there's like what five million blocks every header is around 500 bytes so it would be gigabytes - to fetch the entire header chain but we don't have to do that for Life client there are a couple of clever tricks that allow us to to actually start syncing from some particular points hard to got that point in a client yeah and then how how is it different to actually build a DAP for a light client in a back-end so we know that there are that there are no pending blocks this is this is like one of the main differences because we are not really running the transactions at all we actually don't even propagate the
transactions because we don't have the state to verify if those transactions are valid or not yeah we don't have the state at all actually right we don't we don't have it we don't have block bodies and we don't have receipts so we cannot easily like get we cannot get the transaction data fast or the results of the transactions fast and and there is this network latency involved so even if you are running light client or in your local host you are doing an RPC query to the light client but it has to ask appears in a network to get the results and it increases latency obviously and also some calls are more expensive because then the question arises if my
note is actually like fetching everything from the network so it's leeching on the network how do we control like how do we rate limit those notes how do you control that we are not attacking the the full notes that are providing us data so currently in parity light protocol we have a thing that is called credits and this is a thing that limits how much like computing power of the other node you can actually use so and it obviously is related to the kinds of queries that you are doing on this on this remote node so so we need to be aware that some of the queries might actually be more
expensive than the others and then let's see how we can write it up so as a as a like beginning dub developer what you might do if you want to write a dab that actually displays a latest balance of someone's tokin your 20 token you will probably use web 3 for that and then in this first line we are creating a contract at some particular address we are providing in ER C 20 API for that and then what we are doing we are setting up an interval every 500 milliseconds we will send request to the note that will actually query the balance of that particular contract for
some address provided here okay so what's the problem with this approach it will probably work if you are running a full note like we are asking every 500 milliseconds but even even on full note it may it may behave like a little bit unpredictably because what if the method actually takes more to execute on the note than this 500 milliseconds so what happens is we are actually queuing up a lot of requests on the notes and the note is not able to handle them fast enough for you so sometimes you can even get mapped the latest balance but like some you know straight old call that will be resolved finally and if if we
are not able to handle that fast enough then this will probably break and will crush your note because there will be too many cute connections so you might go like a little bit smarter instead of asking in the interval you can actually wait for the previous call to finish so this I'd update balance filling is actually doing the same things as previously but here we have a little bit of logic that says yeah we want to update the balance and only after it finishes we want to trigger another balance updates but we are trying to target like me average block time size because sorry block time because we know that the balance can only change when the new
block is coming to the network right so we are waiting for it and then if it takes five seconds it's fine we will run and next balance update in in ten seconds if it takes 20 seconds so more than a block then block time then we will actually schedule another call right away too to have to always have the latest balance luckily with recent editions due to notes our pcs we can actually subscribe if we are using WebSockets transfers obviously or IPC transport we can subscribe to the note and be notified about new blocks that are imported by the node so this is how we use web free subscription API so we
say I want to know when there is a new block imported and only when there is new block imported I am updating the balance balance that that in my DAP yeah so so all of this is kind of like patterns that we have to use to write to write our dubs this is kind of like it cerium development tribal knowledge that everyone has to know but I think it's it's actually better to enclose such patterns into libraries and prevent and misuse by providing a good API so in parity we actually had two approaches to this already and the first one is called double-oh-seven
reactive bonds and the idea is that we hide all this complexity we hide this all things that you have to think about like subscribing for new blocks and then asking only and when the new blocks comes into streams that just give you the latest data and you don't really care how they are updated so here you can see I'm importing bond from double-oh-seven parity and then I have a bond that represents the block number and I can map over that bond and display the latest block number on the console and every time the block number changes this will be displayed on a console right away yeah the second thing that we
you could do was to take one bond and actually compose that bond with some other bonds so for instance here we have this sort of an object of all possible blocks in a network and we say for every block number so every time the block number changes I want to fetch the latest block then from this light this block I want to fetch extra data I want to convert the hex two to ASCII and display that on console right and then every time the block number changes or the content of the block changes because we could reorganize a block and this would also be handled automatically here we will get a new a new extra data but the problem so double-oh-seven was based
on computational graph so in principle you could do many of those transitions in parallel like that these parts of the computational graph could be computed in parallel but unfortunately JavaScript is single threaded it was kind of like a simplified version of reactive extensions observables because we didn't support all the methods we just try to make it like feel natural to work with it was written in JavaScript without providing typescript typings the documentation was like a little bit lacking and we were also using the proxy object and that could make it a little bit more magical for like people just trying to use the library so recently we
have tried a new take on the same problem and we have worked on light Jay s library and this is reactive extension so very similar approach to what we did with with bonds but based on reactive extract like extensions and obviously it still has to be light client friendly so we don't try to expose every RPC method that is there we try to expose the patterns in which you use those methods and convert them into observables where you don't really need to care about if it's running on a full note if it's running on a light note am I like trying to spam the note right now by doing that
all those patterns that you have to follow if you want to be light client friendly are enclosed in that library and you are just using this higher level API to to build your DAP so it's written in typescript so obviously the Taipings are there and the the API right now is is very minimal and high level so let me show you how it looks like you are importing a block number stream from Paraty like Jas and you are it's importing the rxjs operator to to modify the string somehow and we are subscribing to block number then piping that through the filter stream and what we will get we are subscribing to every
second block in the in the in the network yeah that's that's pretty much it yeah one more thing the the observables the streams are lazy so we don't really do that in the background all the time but only if you subscribe only if you use it then we are starting the subscriptions then we are acquiring the stuff for you so there is like no overhead by just importing the library obviously we support contracts as well so you can import make contracts from the library you can provide an address and the API and then we take the stream of default accounts so every time user
changes default account you'll be notified about that and then we say for every default accounts we actually want to the balance of that account and obviously this is another observe available so whenever the balance changes you will also be notified in this subscribe console log statement and because in parity our framework or of choice for building from the application this is react we also have a react integration for light J s so if you want to use this values or that are in those streams in your react components you don't have to
build anything yourself you are just importing a decorator from like GS react and then you say I want to get sync status so the values of the sync status in props of the component and the the higher-order component is actually subscribing and providing you the then at the lightest value to the component so yeah like Jas is quite minimal currently it was built to actually build feather so this light wallets that I mentioned earlier and we are still working on the API contributions are obviously welcome you can find us on on github and the future what's what's
coming next obviously we want to extend like Jas to contain more AP ice to enclose more patterns so we are really open for contributions we might be working on UI component libraries so not only this you know lower level stuff but higher level components like buttons that you can you can use in your application and a lot of work in the core part of of parity parity theory inclined is to make parity Theory parity theorem run as a library so that you can compile a parity et reom and use it in your Android app for instance obviously I mean light client of parity theorem and a second stream is
working to compile a parity reom to web assembly so that you will be able to run a light note in your browser for instance either as a chromic tension or like in on the website itself so you are just visiting a website it actually contains parity et reham wasn't light client it's syncing the network right right away and you don't have to go to in fewer you don't have to connect to like local has a eight five four five you are just running the light node inside your browser and that would be about it so thank you [Applause]