solana-improvement-documents/proposals/0047-last-hard-fork-syscall.md

120 lines
4.3 KiB
Markdown
Raw Normal View History

---
2023-04-15 13:27:07 -07:00
simd: '0047'
title: Syscall to get the last hardfork
authors:
- Godmode Galactus (Mango Markets)
category: Standard
type: Core
status: Draft
created: 2023-04-15
---
## Summary
2023-04-15 13:39:08 -07:00
Create a new sysvar `SysvarLastHardFork1111111111111111111111111`, which can
be used to get the last hard fork slot.
## Motivation
2023-04-15 13:39:08 -07:00
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.
Dapp developers may find it useful to know that a hard fork has recently
occurred. This information can help them prevent arbitrage and liquidation
caused by outdated oracle price account states. However, the cluster's restart
process takes several hours; in that time, the world can change, causing asset
prices to fluctuate. As the cluster updates the state of all accounts,
malicious actors could take advantage of the delay by conducting trades using
outdated prices, anticipating that they will soon catch up to the actual
prices of real-world assets. Knowing that hard fork has been done recently,
dapps can manage these cases more appropriately.
## Alternatives Considered
2023-04-15 13:39:08 -07:00
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.
## Detailed Design
### Creation of a new sysvar
Addition of a new file `last_hard_fork.rs` at following location:
`monorepo/sdk/program/src/sysvar` to implement the new sysvar.
2023-04-15 13:39:08 -07:00
We should also implement a new structure to store the last hard fork data
similar to:
``` rust
#[repr(C)]
#[derive(Serialize, Deserialize, Debug, CloneZeroed, Default, PartialEq, Eq)]
pub struct LastHardFork {
slot: Slot,
count: u64,
}
```
`Sysvar` trait should be implemented for above structure.
``` rust
2023-04-15 13:39:08 -07:00
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
2023-04-15 13:39:08 -07:00
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.
2023-04-15 13:39:08 -07:00
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.
2023-04-15 13:39:08 -07:00
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.
2023-04-15 13:39:08 -07:00
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.
## Impact
2023-04-15 13:39:08 -07:00
Dapps will start using this new sysvar 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.
## Security Consideration
None
## Backwards Compatibility
2023-04-15 13:39:08 -07:00
The dapps using the new sysvar 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.