First thing, the easiest question: PVM and RISC-V are compatible. Not from PVM to RISC-V necessarily, but RISC-V can be recompiled into PVM very, very easily. We expect that we will be a target of LLVM in the next 12 months. The alterations to LLVM are pretty minimal to make it work really nicely with PVM, but even before then it's just a very quick translation pass on RISC-V code. It has to be the particular variant of RISC-V, right? So at the moment I think it's 32EC and eventually it has to be 64EC for that next, but it's easy. So there's no worries on using mainstream toolkits to create PVM code.
Good. What services do I expect to see? So, JAM is created for two main things. One of them is to be backwards compatible with the Polkadot relay chain, and the second is for CorePlay, which is a fairly ambitious smart contract, actor-based, highly scalable, synchronously composable system, like a platform, right? Which would support multiple program languages, so EVM, PVM, and potentially others as well. And then there are smart contracts and there are kind of things that are more like actors, and it could also support just indefinitely running programs. The idea is that it's very much what Ethereum is meant to be. It's a big virtual global supercomputer that can host people's code and run it in a sort of shared sandbox. So those are the two services that are really, if you know, that's the success criteria for JAM. It must be able to host these two services.
What other services might be interesting? Well, I think there are a few things that are currently built as parachains that will make sense as services. The two that I can think of, maybe three. One of them would be the bridge hub. Basically, I think bridges, because they don't necessarily need, because they rely on other consensus systems forming a kind of sub-consensus, and the only thing that really needs to be done in Polkadot is checking that sub-consensus is correct. You don't really need the validator network. And if you don't need it, that's the sensible way that you can figure out: is the validator network the optimal solution? If it's not the optimal solution, then probably it's better off as a service or something that sits on a service. So yeah, bridges, so essentially like clients, probably make sensible services. A storage network may also be a very sensible thing to build as a service, mostly because the blockchain element of it is probably not so relevant. What's more relevant is the data availability element, and you probably do that more efficiently if it's built directly as a service.
And the other thing that springs to mind is something that we've mentioned in the JAM chat room, which is building full nodes and running them inside of JAM cores. So this would mean we would be effectively bringing other networks under the JAM security apparatus, which means not only do they get extra security guarantees because they're not being just checked by their own validators but by JAM's validators as well, but they also get, because they're under a common security apparatus, high-speed messaging between them, which at the moment on Ethereum L2s is a bit of a big deal. It's very hard for these L2s to communicate securely and speedily between them. So there are some interesting potential use cases there for JAM. And one mad thing is just run Ethereum L1 as a JAM core. Just don't forget trying to actually client-bridge to it, just run a full node. And it's this kind of mad stuff that we can actually start thinking about doing with the level of performance and bandwidth that JAM brings.
I don't have much more than that. I haven't given it too much thought. I think when we start having real JAM testnets and better tooling and a service SDK, and we just start coding stuff up, we can actually get a much better feel for what's possible. But at the moment, it's really hard to imagine what might be possible on a system that we could only imagine anyway. It's like imagination squared.
My relationship as Gray Paper author with the rest of the team: I'm focused mostly on, in terms of my coding, I'm focused mostly on the on-chain stuff. I've not really touched anything off-chain. So whenever something in the Gray Paper changes that relates to the on-chain part, I'm usually the one that actually puts it in. This is actually a very good thing because I have a very hands-on feel for what's actually going to be possible, efficient, and performant to implement. And I'm not just head in the clouds, ivory tower, just writing random math stuff and expecting to pass the problem on to someone else, which I think is to some degree a bit of an issue in certain other communities.
That said, I am still very much in touch with everyone. The team at the moment in Parity, I think it's depending on exactly who you count, it's about six or seven people that are working on the Parity implementation of JAM. And this includes one or two people on the PVM and a cryptographer. So it's actually only about four or five people, and this has to include the person that's writing the test vector stuff, which isn't specific to what we're doing.
Yeah, I guess that's most of the questions addressed so far. In terms of what I expect and when, I've written a small presentation because I figured this would probably be something that may not... So you're probably all familiar fairly well with the 01, 02, and 03 versions of the Gray Paper. These laid the ground for all the basic functionality. 04 was a big change with ordered accumulation. This had been, if you actually go all the way back to the core JAM RFC from last year in the Fellowship RFCs repo that JAM is sort of based off, you'll see it being mentioned as a kind of side thing. This is something that we might very well want to do, but it's kind of complicated. But it turns out that actually, in fact, we go through, open this up, if we go to the issue that I wrote, it's necessary to have ordered accumulation for doing zero-latency segment I/O.
So you should be familiar by now with the idea that work packages in the refined stage can read and write to this giant data, right? It's petabytes big, it's a huge distributed availability system, and they can read and write from it. But it's only mostly coherent, which means what they write into it in one block they can't necessarily read from the next block, and they certainly can't do it in the same block. If we implement L1, then this is something that has to be carefully designed. But if we implement it well, then we can probably end up with a sort of affinity system where if you are on the same core index, if your work package is on the same core index from block to block, then you can read from the block that you last read from, the work package that you last wrote to the block. So you can basically have one work package that executes at block T and another one executes at block T+1, and the block T+1 can read from a segment that block T written was written. So within the same core, it's totally coherent, totally synchronized, which is a very helpful thing to be able to do, to not have to wait an extra block or two or three before you see what the last thing that you did, what effect it had.
Now there's a big issue with this, which is that you may not know the segment root, because the segment root is only calculated once you've actually run through the work package and gotten the work report. And if you're literally just sending out work packages and all you care about is that, well, I know it was segment index four, this previous work package exported by, they never actually bothered computing it, so I don't know what their segment root is. You can't provide this cryptographic reference, and that's what ordered accumulation basically is. It's not that you get a cryptographic reference, but you get a semantic reference. You can say work package blah, the hashable work package index, segment index four, and it will look up that work package hash into a segment root, and it will do so securely. You can do it insecurely without this, but to do it securely you really need ordered accumulation. And that's what this says. So that's why we have ordered accumulation. It's not just some whim of wanting to be able to provide some sort of dependency graph. There's actually a very particular reason, which is that we can claim that JAM's DA system gives sensible usage characteristics. Not that you have to skip two blocks in order to read something that you wrote out last time. That would be not such sensible usage characteristics.
So that took us to 04. 05, there's already a pull request open for 05. It's mostly complete. I'll probably, as long as there are no glaring issues with it, I'll probably merge it in the next day or two. There are a couple of things that it brings. It brings pre-images after accumulation. So at the moment you integrate pre-images before you accumulate, you're going to switch that around. So basically you can run your accumulation before necessarily knowing what pre-images are going to be introduced into the block. Generally you want to start accumulation as soon as possible, and you don't want to be, whereas pre-images might arrive on the network over the period that you were accumulating, over the period you were deciding what should happen.
We also have a structured extrinsic commitment. At the moment, extrinsic commitments are just a hash of the whole thing, this serialized extrinsic block. So you take the extrinsics, all five of them, you serialize them into some big, I don't know, 50 megabyte blob, you hash that, and that's what you put in the header. This is fine except if you want to distribute parts of this extrinsic individually, then there's no way of proving that this is actually a correct part of this block. Because you have to either provide all 15 megs of the extrinsic or none of it. You can't prove that it's the right 90k in the middle. That's why we bring in this structure. It's basically a Merkle tree, but it's not a strict binary Merkle tree. It's a Merkle tree because we don't need a full binary Merkle tree. It's going to be lots of passing and quite complicated to do, so we just instead hash the, we have a Merkle tree of the guarantees of the reports, because these are the things that you might want to distribute individually around the network, kind of gossip, not quite gossip, but kind of gossip. The rest of it you're probably going to want to just send directly. You're not going to want to necessarily just distribute bits at a time. Also, the work reports make up the vast majority of the block in terms of bandwidth, the space. The work reports make up almost all of it. So it's helpful essentially just to be able to have these things kind of have a separate logistical path to get to the other nodes on the network.
There's also a minor change to the availability spec. The number of export segments is included in there as well as the hash of the segment root. There's also been a bunch of changes to the PVM in 05. The biggest one is that there are 64-bit registers, which should speed things up quite a lot for many common use cases. There's also made clear, very formalized, the paging of the PVM. So PVM formally now has 4K pages, and each page, not each byte, can be either inaccessible, accessible just for reading, or read-write. Prior to this it was each byte, which obviously is kind of nonsensical for real hardware.
There's two new host calls for the inner PVM manipulation, which are essentially allocate and deallocate. And they change these pages: the first host call, which is zero, changes the page from being not accessible to read-write but full of zeros. And then deallocate changes it from being read-write or read to inaccessible. And by determining how many pages that are accessible there are, this will alter eventually the gas calculations. Gas will become more costly. There'll basically be a gas multiplier that makes all of the operations cost more gas if more memory is accessible. So it's in your interest as a program running on the PVM to keep the amount of memory that you can access as low as possible. Why? Modern architectures are fast but can be very slow if they're hitting memory that is not in the cache. This can have a 100x slowdown. There isn't really an efficient way of deciding whether memory is going to be in the cache or not ahead of time, and if you do it at the time, you're basically talking about trying to catalog every memory access and model a CPU's cache in real time, which is obviously really, really slow as well. But a slight trick that we've come up with is to say, well, look, if there's only one megabyte of memory that is accessible, then it's all going to fit in our chosen hardware as L2 cache, which means there is a limit of how slow it could possibly be to read something. And that's what's going on. So we want to incentivize programs not to have so much memory allocated, and that's why we have these very explicit allocation and deallocation.
We're going to introduce another RISC-V extension to the PVM instruction set, which is basically a bit operations extension. That's not, maybe we'll see if this happens in 05. I know it's being worked on, like prototypes in the Polkadot PVM team. If it happens, it happens. If not, it'll be in 06. And there are two more instructions that we'll add as well, basically mem-sentinel and copy, and these will be optimized on the host side for doing copy operations, with the expectation being that this can be a significant performance increase. Right, so that's 05, and as I say, hopefully that's something that will be launched this week.
I expect five more minor versions before we get 1.0. The 06 is essentially feature completeness. So all of the stuff that I think should be in the protocol is probably going to be in the protocol. It's going to be detailed in the Gray Paper by 06. It won't necessarily be the final version of it, it may need some tweaking, optimization. But so GRANDPA, there's going to be an actual reference into the GRANDPA paper, so it's unambiguous. I'll fold in the JAM network protocol into 06. There will probably be additions as we go on, but this will be specific network optimizations as we understand better the dynamics of nodes and trying to process through blocks and author blocks and so on. And we're only going to refine that when we run it on the toaster and actually have larger scale networks running through real-ish applications.
There's also this idea of bringing in one of the additions that has been proposed for the relay chain, MMR, Merkle Mountain Range. Merkle Mountain Range, which is basically it's a fairly small optimization on the structure of doing NMRs. It's super, it's yeah, it's like a more efficient Merkle Mountain Range, but it's still a Merkle Mountain Range. It's just you have a slightly different data layout for it, so when you add stuff there's like an order one computation cost, and your tree depth for stuff that you're most likely to want to prove, which is basically more recent things, is smaller than it would be if you use a regular Merkle Mountain Range. But as I say, it's a very minor tweak. So that'll probably go into 06.
And basically 07 will be toaster tweaks. So when we get actual real performance data, performance data for like emergent network behavior by running nodes, hopefully more than just a Polkadot JAM node. 08 will be the last main set of tweaks, the last main set of non-security related tweaks, and that will be for when we start prototyping services, start running services on it, and say, oh, actually it turns out that to run this, you know, the core chain service, it's really shitty unless we have this particular PVF construct or this particular facility, or we need to optimize this particular network operation. I don't know, but that's where these final application-level tweaks will come in. 09 is mostly focused around security. At 09 we should be launching on Polkadot and having the protocol be audited. And then 1.0 is the final thing.
So yeah, 06 is focused for getting this feature freeze. There's also a bunch of improvements I want to make to the Gray Paper, which is going to make it really difficult to read for everyone that is used to reading it as it is. But I think it's actually really important for getting into, because my biggest annoyance with the Gray Paper is that I've used subscripts. So when I use subscripts, I sometimes use it for indexing an element in a sequence or for naming a field. And although they're generally unambiguous as to whether it's a field that needs to be done or a subscript, it's still the same visual language. And so you kind of have to think, hold on, this thing that's being subscripted, is it a sequence or is it a tuple or whatever? And that's not so good. So I'm going to change it so that field names are always uppercase. So if you see something that's uppercase, it's going to be a field. And if you see something that's lowercase, it's some sort of Scala variable that indexes into a sequence.
There is at least one thing that is duplicated, which is this bit indexing function, a bits function. Basically there's one that's like symbolic and one that's like bits in typewriter letters. I'm going to duplicate those, gray paper referencing, maybe a little the EC referencing potentially as well. And it's for 06 that we really try and get the test vectors complete for the M1 stuff, possibly some of the M2 stuff, definitely for the M1 stuff. What the test vectors should cover, the full range. I'm not saying they're going to be the final test vectors because there'll still be tweaks to be made, but they should be comprehensive.
What do you mean by test vectors? The test vectors in JAM, so files, all stuff will be ready together with 0.6. This is what I mean. Or are you talking about the milestone one? Yeah, the milestone test vectors. This is a sequence of blocks you need to be able to import to come to this block edge, basically. Yes, now that I'll go on this a little bit later because it's not the thing, but if you like, this is the training data, right? Not the actual final test data, that's separate, and that's not given to teams, that's internal to the Web3 Foundation. But the training data, so the information that you get for testing implementations against, that should be comprehensive by the time the 06 series is complete. I mean we're getting there, but you know, there will be a bit more to come, and that's the aim of that. That ties roughly in with the lifetime of 06, because after 06 there should be no more features coming. It should really just be tweaked based on usage.
And in fact even within 06 there's not that much here that's features, right? There's the MMR stuff which is sort of a feature, but the JMP is already specified just outside of the Gray Paper. GRANDPA is already specified. So in fact 06 isn't really bringing anything new, it's just tying everything together.
So do we get the actual blocks to be imported also at the end of 06? Yeah, I mean yes. And with 06, I mean it might be 06 might be a little bit later, but around this time. 06, 07 is where we'll try to provide the test harness requirements. Test harness requirements will be what your implementation needs to do in order to run our internal conformance tests. Right, this is probably going to be an RPC interface where there'll be, I don't know, two or three or four different RPCs that basically take this message, pretend this message came from a network, maybe one of them import this block data is almost certainly going to be one of them, and tell us what message you want to send to someone on the network. Maybe the networking, we're not sure yet. This may happen also just as a sandbox thing, so we just provide a fake network sandbox and you just have to run under a Docker environment with this fake network configured.
But for M1 there is no requirement for networking anyway, and so for M1 it will probably just be, here is a stream of blocks, import them and tell me what your status is. And we will specify that RPC when we get to M2. As I say, there'll have to be some sort of networking thing. So whether it's an RPC and it's up to the client to fake the networking for itself, or whether we provide a Docker environment with a fake network and the client can just pretend it's on a real network, uncertain yet, but it'll be one or the other probably. And then it will basically be checked on not only what its state is but what networking it sends out. And then when it comes to M3 and M4, it will be when it sends the networking out, right? This will be crucial.
So imagine essentially, you know, we're all done with this and anybody could design a client, run it against the toaster, because that's how it's called, right? And then you can actually verify the whole implementation. Yeah, yes and no. So you'll be able to verify against the training data, yeah, which we'll publish some of. But then when it comes to actually doing the conformance testing, and for that matter the performance testing, this will happen with procedurally generated data. Oh okay, yeah. So you won't know what you're going to be testing ahead of time. It's kind of like network fuzzing. Yeah, kind of. And as more implementations, so initially it'll be the Polkadot JAM implementation that we'll be doing the conformance tests against, and then as we gain confidence, like basically as other implementations pass the conformance tests, they'll also be part of the fuzzing thing. Yeah, right, and that's cool. As we find compatibility issues, so basically as the conformance testing finds issues, we'll isolate these particular circumstances and they'll become part of the training data. That's cool. And is this then deterministically generated, this procedural stuff? Like for example what TigerBeetle did, I don't know if you're aware of this, they got this kind of random number and everything is generated out of this random number, so you can actually replay to find... Oh I see what you mean. Yeah, yeah. It quite possibly is, yeah. I mean we should be able to, assuming that the cradle itself is deterministic, we can certainly reproduce the input data that gave the problematic situation. That would be cool.
I have one question about the performance, and you touched on that. I believe I recall some mention about having some sort of relative performance benchmark. Is there any... Yeah, so there will be a best performing client likely and a worst performing client. That's a cool idea. What does Polkadot performance actually mean in objective terms? What does performance mean? So Polkadot performance is probably going to be within some particular percentage of the best performing client. So let's say, finger in the air, 80%. So on average, you know, work package execution and block import must happen within 80% of the time, within whatever, 25% of the time of the fastest implementation. Then there's the question of what we require for M4 as opposed to what we require for... How is this going to work? So yeah, in essence what we want is to say there must be three, ah yeah, that's it. So all three implementations before we launch the network, there must always be three implementations that anyone can run. So before we launch the network, we want these three implementations to be no slower than 80% of the speed of the fastest implementation. That's the condition for launching the network. Once the network is launched, once we have these three, then what we want to do is do it not on the basis of the fastest one, because the fastest one might get faster and then there wouldn't be three performing sufficiently performing implementations, right? And we would be like, ah, we got to stop the network until this guy gets fast enough to then be three, that's no good. So then we take it on the third fastest implementation and we say you must be within, let's say, 5% of the third fastest implementation, which means you might get knocked out of the top set. Like if you're a startup as being the third fastest implementation and then some other implementation comes along, passes M5, and they turn out to be sufficiently faster than you and the second fastest implementation, that you are now no longer within 5% of them, then you would no longer be considered a sufficiently good implementation for validators to run. Right, so there's going to be a continuous competition to be within 5% of the third fastest implementation. But some thought has gone into this, no doubt that will be shared. Time, yeah, yeah, for now it's like focus on it more.
Right, so then 07. So there are probably some, I can already think of some things that we're going to want to change when we probably by the time we get to putting things on the toaster. Not least the network protocol. I know there are at least a couple of things that we want in the network protocol that aren't in there at the moment. So that's probably where the bulk of the Gray Paper changes for 07 will be, I guess. We'll probably want to optimize the erasure coding. We'll probably want slightly different erasure coding parameters for work bundle erasure coding compared to segment erasure coding. Remember they both run on this, what is it, 682 byte sort of chunks, which is not especially, because the thing is if you're doing it using a regular binary erasure code, then you have to, it has to be like 2 to the 9, like 512 that you got to be working on. You can't work directly on this 341 size, right? And this means that you're wasting a third of your points. You're basically doing an erasure code for a 512 point data where you actually don't care about the last third of them, and that's not so great. So we'll, it's kind of fine for doing the segment stuff because, you know, just the way it works out, it's probably the optimal way of doing it, just because the amount of, it's really hard to parallelize on the CPU, at least with the current algorithms, and the number of, it's still substantially faster to do a 2 to the 9 than like, it's still substantially faster to do like 8 2 to the 9 than like 4 2 to the 10 on a CPU, because you can usually do about 16 at a time anyway on a modern CPU, and unless you're thinking everything is going to be coming from the same index, a set of indices, then you're not going to be able to parallelize. If we can get it so that if we find an implementation that allows for segments to be coming from or chunks to be coming from different sets of validator indices, different sets of indices essentially, then this changes, and we probably do want to alter the segment EC. But for now I think it's probably optimal. The work bundle EC definitely shouldn't be that, because the work bundle is going to be coming from the same validator in the same session, and there are going to be like megabytes of it, so it's inherently very parallelizable. And so we want work at the highest size possible, and that's probably going to go up to 2 to the 12, 2 to the 13, whatever. We've done, we've got some benchmarks here. It's definitely not 2 to the 9, we know that much, and even if it is 2, it's definitely not only using two-thirds of the data. Yeah, data logistics optimization is probably, again, these go hand in hand with the JAM optimizations, just making sure that data gets between nodes quickly and easily.
And then the maybe PVM tweaks that we need for, I put here inner continuations, which is basically the ability to suspend PVM instances between blocks. And this is one of the key features of JAM, basically the ability to run a virtual machine and make it look within the virtual machine as though it never stopped running, even though it's running between many different blocks. We may need to tweak that, we won't know until we actually start coding with this.
08, as I say, continues along this theme, but rather than post-toaster, post-service prototyping. Maybe, so one of the things that I've touched upon a little bit in the JAM chat room but is a very important point is the difference between accumulation and integration. So accumulation takes the results of a work item and does some code, right, execute some code on these results with access to some synchronized database, the on-chain database, but it doesn't necessarily integrate it into some final world model that this service maintains. It could for example queue those changes or discard the changes entirely, or queue them and then eventually discard them, but unknown at the time which will happen. Now what integration is, what I'm calling this much more, this higher level concept of, without the possibility of ever reverting, committing these whatever these changes mean for this service into its state. And it's integration that we care about when we're doing cross-service composition, right? If you're, I don't know, exchanging a token between two services, very simple crappy example, you want to know that the token has actually gone from one service to the other one irrevocably before you do the same on the other side, right? They have to both have had this high-level state integration. It's not enough just to say, well, I know that the other one has run its accumulation code on this, because hey, maybe the token doesn't exist anymore, maybe it's somewhere else in the meantime, or whatever else. So integration is this higher-level effect of accumulation that isn't necessarily, I mean if you've got like totally infallible accumulation code, then they're amount to the same thing. But if your accumulation code has conditions in it, or different things may happen depending on what's just happened before, or could fail in some way, then they're different things, and you need some means of ensuring that integration has happened when you're doing cross-service collaboration.
Maybe this is worth it actually having as a facility inside of JAM. Maybe don't know yet, haven't developed any services yet, haven't tried to make services actually interact with each other yet. But when we do this we might find that there are certain patterns that are very useful and efficient to implement with existing primitives, and we actually want to have some additional primitive for this. This would just allow this atomic transactions kind of thing. Basically, yeah. So yeah, it would allow you to say, right, I know that this other service wants me to do this thing, but I don't want to do this thing until I know it's done the other thing that I want it to do in return. And it's essentially going to be a state change over multiple services. I mean the way that it would be done at the moment is service A and service B may have what I've called an entangled work item, which is a work item that, well there's two work items, one for service A, one for service B. They're codependent. So their effect on their service's state is conditional on the other one having an according effect on its service's state. And it's like you don't want to enact one of them without being sort of guaranteed that the other one will be enacted as you expect. And it's not enough just to assume that they're both going to hit accumulator, yeah, unless your service is trivial. If your service code is trivial in both cases, then you can probably just assume if accumulate happens then it's probably fine. But unless it's trivial, then you need some sort of thing of, hey, I got this work item, and as long as I hear that you got your work item and are cool with it, I am going to do my thing. And it's kind of like, I'll do this if you know, it's like, say I'm ready, are you ready? And as long as you get the I'm ready from the other side, then you can go ahead. Yeah, because you know that the other side will go ahead. But you have to wait for this I'm ready, yes I'm ready thing. And it's like maybe we want a facility for doing this, maybe we don't. A way that you could also do it is just storage. So in your service storage you have a special place that's like, I am ready for, I've received this work item, I know it's entangled with your work item on that side, I'm ready to enact on this. Once you're, I'm going to read your state, and if I see that you're ready, I'm going to enact it. But probably you wouldn't want to have to read it every time, so you probably want to make some sort of transfer message. And I mean it's doable, totally, it's possible, but maybe we want a facility for optimizing, especially if we expect lots of cross-service composition.
Yeah, we may want tweaks to the PVM. That's I think less likely, but it's possible. We may want tweaks to the DA. We may want tweaks to the work package dependency system, so the ability to have X dependencies, the ability to have these segment root work package hash lookup system that is just introduced with ordered accumulation. And then in general there are a bunch of things that, as I say, represent the success criteria of JAM, like core chains, CorePlay, service composition. And as we start implementing this stuff, we'll be better able to understand if JAM as it stands can actually serve these needs sufficiently well. So that's where 08 is getting into. And after 08 is done, it's like, right, this is JAM 1.0, right? This is actually our kind of 1.0 stick in the sand. We're not adding anything new at all at this point. We're not tweaking it. It's just what it is. 09 goes off to audit, and the only things we change are what come back from audit. And then 1.0.
So service development, which probably is kind of helpful to know is coming. As I said, I'm kind of in a pretty good position to be starting to fiddle around with services now. Once I've got 05 out of the way, it'd be really handy to find someone to do some of this grunt work on the Gray Paper. It kind of takes quite a lot of my time. But anyway, until I find someone to do the grunt work, I guess it's me. So it's not going to be my 100% focus, but I should be able to dedicate quite a bit of time to it anyway. And first thing will be this basic JAM SDK. So this is something we can publish. It'll have all the basic data types in, and just basically a Rust build system, so you can code a JAM service in Rust and build it into a PVF. As I say, I'm hoping to get that, we already have it internally, it's just kind of tied into the rest of the code base, to isolate it a bit. By the end of the year it would be nice to have the final core boot service, which is this bootstrapping service that we can put in a genesis block. And probably will also, I've not mentioned the authorizer service, the authorizer code for this. I mean there's a null authorizer which just returns true, it's a very, very easy bit of code to write. But maybe we also need this as well. I don't think it's that important at this stage though.
We have ideally in the first quarter of next year what I've called CoreVM, which is, actually right, so core boot basically has instructions, a bag of instructions as a work item which get passed into the refined stage. Instructions might be creation of a new service designated by the group, assigning for time-lessening a new service, so basically taking another service and giving it this privilege, introducing always-accumulate services new with 04, transferring balances, or soliciting of the gets and prems. So all of the stuff services need, basically. So then the thing after that to be coded up is, as I say, CoreVM. This tests the inner PVM functionality. This I think is really, once we get this working, it's like, you know, there's a big weight off the shoulders, because it's like if it can do this, it can probably do everything else. And this will probably be where we base the performance tests. So for M3, more or less, how fast can you run CoreVM and how many of them can be run? So the concept is you just give it a regular no-std compiled binary and it can just run it like a regular computer can run it. And there'll be some I/O, so you can basically have like a database layer that will be your main I/O, can write stuff into the state storage, service state storage, and read from it.
There is nothing special about the binary, right? That's the clever thing. The binary is just like a regular binary. If you want to put an infinite loop in there, you can put an infinite loop in there, and it will just still work as you would expect if you run it on a regular machine. The PVM executes as part of refining. RAM is stored in the segment DA, like huge data lake, and paged in and out as needed. And the VM is cleverly suspended and resumed as needed. So if it hits memory that isn't in the work item, that can't be fetched in as a page because you've already fetched in too many pages or whatever, it just suspends the VM and it continues it in the next work item.
I find this very interesting what you just said. So you can actually make an infinite loop, yeah, and it will just run, and then in case it slides, it will be just suspended and it will continue. So actually the punishment is now if you write bad code, but you're broke. Yeah, that's cool. Yeah, yeah, exactly. Like you don't need to be concerned about, I mean you can be concerned about gas, but it's just going to cost you. Yeah, exactly. And if you're willing to step up the cash, then yeah, just write whatever code you want. So it's different in terms of like comparing to Ethereum. Ethereum doesn't let you, if it's too much gas to use, you just can't, it won't execute. You can in this case, you can, but you just spend a little bit. Iteration, yeah. I mean realistically, if you're writing just regular, if you take Doom and compile it, the point is you should be able to build Doom and run it in CoreVM, right? In CoreVM. It won't run very, very well. I don't know actually, maybe it will run quite fast, but the thing that will be the limiting factor isn't the compute power, it's the memory bandwidth. Because every 4K page you hit, then you have to, it has to come in. You can only have in every six-second work package 2,048 pages. So if everything fits, if Doom fits into 8 megabytes, which it might actually do, then it should run at almost native speed. That's cool, that's cool. Yeah. Yeah, so the idea is that this will probably, some gaming, some old games will actually run. Yeah, I mean games, what you can definitely do is take, you know, like an Amiga emulator or a Spectrum emulator and just run it in real time on chain, which is pretty mad. Yeah, that's, we should create a contest for that, some nonsensical contest. It will be fun. Nonsense.
Services, that's your original question. I think also as a programming model is like kind of like we are stuck in this way of thinking where things are like, blockchain programs are like this block-based and transaction-based things. Like even today if you want to write like a substrate chain that kind of just fills the block with the impet, you still have to think of it like, you have to write it, it's not like one entry point, it's like, you have to think about like, you know, you run and then when you resume next time what do you do? Like it's a very different... Multiple migration is just so complicated. Yeah, exactly, that's how it works in the current model. But the new model can just be any function, yeah, just be wild. Exactly, and that's, yeah, it's kind of mad to even move into this paradigm, so used to the other one. But my hope is that we can sort of start taking regular, you know, graduate or undergraduate level programming books and actually just write these algorithms, write these pieces of code. I don't know, maybe after translating to Rust, probably not though, because like C++ can be, C can be compiled into PVM pretty easily, and then just execute it on chain and say, well look, you know, it's just a regular code. Try to wrap up five minutes. All right, sure, I'm on to, I think was almost the last slide, got two more left.
Yeah, so then after that, midway through next year, probably going to be more like Q3 I guess, we have core chains, or whatever it is that Shawn wants to rename it to, which is basically just the replacement for the relay chain functionality. So it does message passing, finality, thought tracking, and good time execution verification. So I'm kind of hoping to put it on, I mean we'll probably, the Polkadot JAM team will probably start on this and like do some prototype code just to sort of show roughly how it should go. And then I'm hoping to basically get the Substrate, the current Cumulus team, at least one or two of them, maybe you can just form a two or three person team and do, but I mean the logic's already written, right? It just needs porting into a service. So I'm kind of hoping it's not going to be that much effort for them.
And then finally, CorePlay, which is CoreVM plus the hard thing, which is the interactor composition. And this is still a little bit of an unsolved problem, I think in general it's an unsolved problem. Not that it's unsolved for us, it's just like if you have arbitrary numbers of actors with arbitrary constraint satisfaction requirements, like basically where they can't run unless that actor gets to this point and this memory has been fetched in, and there's this amount of gas free to be used, and then you have to basically take all of these constraints and create the optimal partitioning of actors into separate synchronously composed work packages, with amounts of gas for each one and execution ordering for each one, kind of scheduling for each one. I think it's pretty hard, but it's what operating systems schedulers do all the time. So I think it's also not, it might be theoretically unsolvable, but I think there are algorithms that get you quite far, you know, heuristics and so forth. So yeah, I think it's probably doable. Then the question is whether it's doable in a decentralized fashion. Probably not in any really secure way. But then the question is, well, how secure does it need to be? It's probably fine if it even stalls for like a block or two, as long as there's like a way of doing leader passing and making sure that the same malicious leader can't just stall the network for a sufficiently long period of time.
A question, say, would it be possible to have that kind of a service which you just want to run like for example today, and then when it's necessary, you know, next week only one state transition, and three months later another state transition, and for the rest actually I don't care, I just want to inherit let's say the fundamental, let's say security of the network. Yeah, there's nothing, I mean as long as you're willing to pay the, keep a deposit down for the storage costs. Okay, definitely. And but say can I just only pay for when I use it, and then the scheduler will just give me some time just to execute? That's not specifically within CorePlay. Okay, CorePlay is the service, okay, that will be an actor within CorePlay. And then the question is, well, are you willing to, like with CorePlay, the actor's memory would be stored in the distributed data lake, which keeps it around for 28 days. If you don't hit your actor, or if you don't hit one particular page of memory of the actor for more than that, then it wouldn't be there when you want to run the actor again. So there would need to be an additional service that basically checks to see if your actor is getting old, and if it's getting old, to store that data in some other longer-term data storage, keep alive. And then you'd have to pay for that service as well, right? And this is why I say that actually having a probably a long-term data storage service sitting directly on JAM is probably a sensible one. Like not in JAM, but as a first-class thing rather than as a parachain, almost like a B-tree through B-tree. And that's it.