Define system bootstrap
JakeOShannessy opened this issue · 7 comments
Now when we register procedures we need to include a "source" capability from which we derive a subset. The problem is, how do we define the first procedure? From where does it source its capabilities?
I believe the best solution is that the kernel comes with a default entry procedure that is locked to the account which is deploying the kernel. This entry procedure will pass syscalls directly from the owner to the kernel. It is then up to the owner to deploy the correct restrictions etc. Different organisations will require different initialisation and handover protocols, but this should handle them all in general.
Another way we could do it would be similar to how we do it in tests: if the length of the procedure table is zero, you can register any procedure which would be set as an entry proc.
They key question then is "by what mechanism do you register a procedure?". The reason I proposed a default entry proc is that it will perform any registration via the syscall mechanism. This means that the kernel only has the one interface, syscalls, which I think is great from a simplicity and security perspective. All complexity to do with bootstrapping is then pushed into this initial entry procedure which can be deleted immediately after bootstrapping (at the user's discretion).
There is also some other logic which that bootrap entry proc will need to contain. For example, who can bootstrap the kernel? Presumably only the person/account which deployed it. If we don't have a bootstrap proc but rely on the kernel to do that registration and authentication, then that's more complexity we need to bake in to the kernel which will probably only used once.
Here's my proposal:
As part of the constructor/deployment code of the kernel you must supply a single Ethereum address. This address will be registered as the first entry procedure (procedure name TBD) with all capabilities. So the procedure will be as follows:
- The user must deploy an entry procedure to Ethereum first. We will provide a good example of a bootstrapping procedure, but they can deploy a custom one if need be.
- The user will then deploy the kernel, providing the address of this initial entry proc as an argument.
- While deploying itself the kernel will register this proc as the first proc. This happens in the deployment/constructor code of the kernel contract. The deployed kernel knows nothing of this process and has not bootstrapping code. As far as it knows it has always existed in the same state.
Ok, let's do that with the constructor in a separate KernelInstance.sol
file.
A proof-of-concept of this was included in #129 and the tests have been updated to match. It's currently just sitting in TestKernel. Next step is to move it to a better location once I get a better handle on the interactions of constructors and inheritance.
KernelInstance.sol has been created and the boostrap has been moved to that.
Something to be careful of is now that we have KernelInstance
, we should be aware that plain Kernel
will have different characteristics. I think we should consider a deployment of KernelInstance
to be a true instantiation of our kernel, and that Kernel
on its own might not be sufficient.