Multicall: Blockchain State Management in the CDP Portal

EDCON 2019 · 12 Apr 2019 · 10:34

Michael Elliot explains how MakerDAO’s CDP Portal led to Multicall: polling many variables created excessive requests and inconsistent state from nodes at different block heights. He shows a contract that aggregates reads and returns their block number, plus a JavaScript watcher that rejects stale responses, reports changed values and transforms results for the interface.

Speakers

Topics

From EDCON 2019, hosted by EDCON.

Transcript

so I would like to introduce the next speaker his name is Michael Elliot he is a blockchain engineer and maker down and yes welcome and you would be talking about sort of blockchain state management in the CDP protocol yes sorry great thanks hi everyone I'm Michael Elliott from make Adele and last year I worked on the development of the CDP portal which is make his official DAP for creating and managing city piece so during the development of the CDP portal there quite a few challenges that we

accounted and so this talk is about those challenges and some of the solutions that we came up with to solve them and one of those solutions was multi call which is the library for managing state in the city portal so this is the UI here for the portal and as you can see there are quite a lot of variables that we need to track and so if you kind of think about what a DAP is a front-end app it's really um it represents the current state of certain values in the blockchain and so we needed a way to do that and we achieved it by polling so if we're polling for say 20 or so variables and the way that web 3 works with that is that each

request will go out separately so every 5 or so seconds of rare polling that ends up being a lot of different requests and that was the first challenge that we encountered this sort of web 3 request overload and here is what the the network tab looks like in Chrome after a while and to make matters worse before what the browser's work before a request goes out there's a pre-flight request to check if the actual main request has permission to be made so that doubles the amount of requests now that are going out and that's just not ideal and it degrades the performance of the DAP over time so that's the first challenge and the

second challenge is related to the first because all of these requests are going out separately independent of each other and let's say that most users are using meta masks and their forearm in fur ah we don't necessarily know which in fury node those requests are going to hit and not all in fury nodes are in sync so some inferior nodes might be like one block behind and out of date and so you can imagine a scenario were in the Mississippi portal for example it uses creating a CDP it shows the animation we pull for variables we find that the city P's being created we show you the congratulations screen and then one of the other variable requests that goes

out hits a node that is one block behind from when that CDP hadn't been created yet and so we get a variable back that messes up the state of our DAP so we needed a way to solve for that and this is what we could visualize that looking like so you've got meta masks there and the the different variable requests going out to each different node with its own blockchain state the last node there is one block behind so we get a value back that's not up to date with the other values going with the other variables coming back so the solution that we came up with was we thought hey

wouldn't it be cool if we could just make a custom smart contract which we deploy that would go out and it would be able to just from one request so that's my contract look up all the different variables that it needs and then return it so that'd be one request one response so if you were to visualize how that looks it's something like this so we have our values to aggregate a contract so we request we go out to the one node then it would look up all the state from that blockchain state and we had the guarantee that all of those values that are returned from the same blockchain height that saw was the first problem the second issue was solved by returning the block number within the

smart contracts it because we're in a smart contract we had the ability to also turn return the current block number or the block height and this worked really well so now we're able able to make one request every few seconds and return a large amount of variables however yes so now we know that all of those variables are from the same block and also which block that is and that's usually important so for example if we were to look at the block number that's returned from each each response if it's the same block number or lower we can just discard it we know it's an out-of-date node and we can immediately request the values again so

this is the source code for the valley's aggregator contract and as you can see there are quite a lot of variables here that we're looking up the the problem with this though is that every time we wanted to look up a new variable we would have to update this smart contract and then redeploy it which isn't necessarily ideal and it's also only specific to our dap then we thought hey wouldn't it be cool if there was a general-purpose solution to this problem so a way that we could decide on which variables we wanted to look up on the fly when we make the request when we send it into a smart contract that could then go out and look up those variables

and return it along with a block number and so that's exactly what we did and we call it multi call so this was kraid is that it's available there if you want to have a look at the repo all of our stuff is that open source and so this is the source code for the multi core smart contract with a bit of assembly magic we're basically just taking in an arbitrary number of of state lookup so it's my client back addresses function signatures and arguments and return results and then we go through we leap through those make the calls to look up the different variables from the

functions that are called aggregate them all together and return them along with the block number so this works really really well however we've still needed a way to be able to generate the call data that is sent to this smart contract because of the very specific format that it accepts and a way to decode the result and put it into a format that our front-end app can consume and so then we created a JavaScript front-end library called multi call that is so multi called is it takes care of the polling and and also checks the the block number that gets

sent back to ensure that it's not from the same block or or lower so it's completely obstructed away from the UM the front-end app they can just focus on looking up the variables and another cool feature that we added we thought wouldn't it be cool if it could also check the state of the the value of the variables returned and only nap know about when those values change so if you think about it adapt only really cares about the values when they change not if they're the same result and then finally we can do result transforms which is the way to basically run like a custom function over the result he gets back so to convert it for

it to a currency object for example or change the precision maybe convert it to way from way to ether and so this is how we would use multi call so first of all we would configure it in this example we'll pass in main it in Fuhrer and then importantly we would define our calls so in this example we are looking at the total supply of rapt ether and we're returning the value when assigning it to the unique key here total supply with and then just after that we are applying a transform over it to convert it from way to ether and change the precision you know small places across the left

and then the second one we're looking up here is the balance of make Kara the make of balance of a particular address and assigning it also took unique key and then we simply call Crais watcher passing the calls and the config and then we can subscribe to updates so the first time this runs all of the variables that we're tracking will come through this event listener and then only subsequent on subsequent times only when they value changes we'll add up ads at be informed of those changes and we can also subscribe to new block numbers we want

to because that's being returned from the smart contract as well and then to kick it off we simply call watcher dot start watch and then that's it now ow library is watching for state changes on the blockchain and we can be notified of any state that gets changed so that's that's a multi call in a nutshell and I encourage any tap developers wanting to optimize their daps that may be encountering this this problem and wanting to have atomic reads to check out the source code yeah thanks you so much Michael I should also

mention he's one of our own he's from he flew all the way from Perth so I just wanted to ask you Michael what what would be the next thing that you're working on could you share that with us please yeah so currently um as lot of you're probably aware makers working hard on ulti collateral die so I'm currently working on the development of the MCD CDP portal or the CDP portal for multi collateral die thank you so much thanks guys [Applause]