changing from sysvar to syscall
This commit is contained in:
parent
62f631f4ea
commit
30c790861b
|
@ -11,22 +11,19 @@ created: 2023-04-15
|
|||
|
||||
## Summary
|
||||
|
||||
Create a new sysvar `SysvarLastHardFork1111111111111111111111111`, which can
|
||||
be used to get the last hard fork slot.
|
||||
Create a new syscall which can be used to get the last hard fork slot.
|
||||
|
||||
`fn sol_get_last_hardfork_slot() -> Slot`
|
||||
|
||||
## Motivation
|
||||
|
||||
In Solana, when the cluster cannot reach consensus, it is restarted using
|
||||
`ledger-tool` with a hard fork on a slot. A hard fork is usually done on an
|
||||
optimistically confirmed slot which was voted on and accepted by 50% of the
|
||||
cluster but still was unable to get a supermajority. The cluster is then
|
||||
restarted from the hard fork slot, and all participating nodes need to restart
|
||||
their validator specifying the hard fork slot. Once all nodes participating in
|
||||
the restart effort on the hard fork exceed 80% of the total stakes, the restart
|
||||
is successful, and the cluster continues from the hard fork slot. So hard fork
|
||||
is a tool to intentionally fork off the nodes not participating in the restart
|
||||
effort. After successfully restarting the network the hard fork slot is stored
|
||||
in a variable called `hard_forks` in bank.
|
||||
In Solana, when the cluster cannot reach consensus, it is currently restarted
|
||||
using `ledger-tool` with a hard fork on a slot. All participating nodes need to
|
||||
restart their validator specifying the hard fork slot. Once all nodes
|
||||
participating in the restart effort on the hard fork exceed 80% of the total
|
||||
stakes, the restart is successful, and the cluster continues from the hard fork
|
||||
slot. So hard fork is a tool to intentionally fork off the nodes not
|
||||
participating in the restart effort.
|
||||
|
||||
Dapp developers may find it useful to know that a hard fork has recently
|
||||
occurred. This information can help them prevent arbitrage and liquidation
|
||||
|
@ -41,80 +38,56 @@ dapps can manage these cases more appropriately.
|
|||
## Alternatives Considered
|
||||
|
||||
No alternate considerations; we need to have the value of last hard fork slot
|
||||
while executing the dapp to correctly treat this case. We cannot have an
|
||||
account because then it should be updated just after the restart is successful,
|
||||
which will add complexity. The best way is to create a new sysvar to get this
|
||||
information during execution of transaction.
|
||||
while executing the dapp to correctly treat this case. We cannot have an account
|
||||
because then it should be updated just after the restart is successful, which
|
||||
will add complexity. The best way is to create a new syscall to get this
|
||||
information during execution of transaction, which will help us get last
|
||||
hardfork slot without any interface changes for the instruction.
|
||||
|
||||
## Detailed Design
|
||||
|
||||
### Creation of a new sysvar
|
||||
### Creation of a new syscall
|
||||
|
||||
Addition of a new file `last_hard_fork.rs` at following location:
|
||||
`monorepo/sdk/program/src/sysvar` to implement the new sysvar.
|
||||
The implementation of this syscall is pretty straitforward. In solana client all
|
||||
the hardforks for a cluster are stored in the bank structure. The last hard fork
|
||||
slot can be retrieved and then stored in invoke context, so that the executing
|
||||
dapp can access it.
|
||||
|
||||
We should also implement a new structure to store the last hard fork data
|
||||
similar to:
|
||||
For other clients, we have to get the last hard fork slot information and make
|
||||
it accessible to the runtime of the dapp.
|
||||
|
||||
``` rust
|
||||
#[repr(C)]
|
||||
#[derive(Serialize, Deserialize, Debug, CloneZeroed, Default, PartialEq, Eq)]
|
||||
pub struct LastHardFork {
|
||||
slot: Slot,
|
||||
count: u64,
|
||||
}
|
||||
### Overview of changes for solana client
|
||||
|
||||
The hardfork data is available in the `Bank`. The structure `HardForks` contains
|
||||
a vector with all the previous hard forks. The vector is also sorted when we
|
||||
register a slot. So the last element of the vector is usually the last slot at
|
||||
which hard fork was done. We can get the last hard fork slot from the bank and
|
||||
pass it to invoke context structure. We can register new syscall in the file
|
||||
`definitions.rs` where other syscalls are defined.
|
||||
|
||||
```rust
|
||||
define_syscall!(fn sol_get_last_hardfork_slot() -> Slot);
|
||||
```
|
||||
|
||||
`Sysvar` trait should be implemented for above structure.
|
||||
|
||||
``` rust
|
||||
|
||||
crate::declare_sysvar_id!("SysvarLastHardFork1111111111111111111111111",
|
||||
LastHardFork);
|
||||
|
||||
impl Sysvar for LastHardFork {
|
||||
impl_sysvar_get!(sol_get_last_hard_fork_sysvar);
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Loading of sysvar during banking stage
|
||||
|
||||
The hardfork data is available in the `Bank` structure in the field
|
||||
`hard_forks`. The structure `HardForks` contains a vector with all the previous
|
||||
hard forks. The vector is also sorted when we register a slot. So the last
|
||||
element of the vector is usually the last slot at which hard fork was done.
|
||||
|
||||
We can get the last hard fork slot from the bank and pass it to invoke context
|
||||
structure. We also have to add a new field to the structure `SysvarCache` so
|
||||
that this data could be efficiently cached. Now we can easily load the last
|
||||
hard fork data when sysvar is called from invoke context.
|
||||
|
||||
Create a file `monorepo/programs/bpf_loader/src/syscalls/last_hard_fork.rs` to
|
||||
declare syscall class `SyscallLastHardFork`. This helps to initialize the
|
||||
strucure `LastHardFork` from invoke context and sysvar cache.
|
||||
|
||||
Registering `SyscallLastHardFork` in the file
|
||||
`monorepo/programs/bpf_loader/src/syscalls/mod.rs` in method
|
||||
`create_loader` like other sysvars.
|
||||
|
||||
### Updating documentation
|
||||
|
||||
We should add correct documentation for the new sysvar in `sysvar.md` file.
|
||||
We can then return the data of last hardfork slot passed to the invoke context
|
||||
in this functions implementation.
|
||||
|
||||
## Impact
|
||||
|
||||
Dapps will start using this new sysvar to correctly address the security
|
||||
Dapps will start using this new syscall to correctly address the security
|
||||
concerns during network restart. This will increase the reliability of solana
|
||||
cluster as whole and make dapps more confident to handle edge cases during
|
||||
such extreme events.
|
||||
|
||||
As the method is syscall the dapp developers do not need to pass any new
|
||||
accounts or sysvars to the instruction to use this feature.
|
||||
|
||||
## Security Consideration
|
||||
|
||||
None
|
||||
|
||||
## Backwards Compatibility
|
||||
|
||||
The dapps using the new sysvar could not be used on solana version which does
|
||||
The dapps using the new syscall could not be used on solana version which does
|
||||
not implement this feature. Existing dapps which do not use this feature are
|
||||
not impacted at all.
|
Loading…
Reference in New Issue