solana-labs / solana

Web-Scale Blockchain for fast, secure, scalable, decentralized apps and marketplaces.
https://solanalabs.com
Apache License 2.0
13.02k stars 4.19k forks source link

BPF loader not available by default #1565

Closed jackcmay closed 5 years ago

jackcmay commented 5 years ago

Solana should load the BPF loader at boot using a known pubkey so clients don't have to loader their own instance Can we use a key similar to SystemProgram where its a hardcoded small number (E.g. 5)?

Where is a good place in the boot-up sequence to do that?

@mvines @garious

garious commented 5 years ago

First thought on where to load the loader: https://github.com/solana-labs/solana/blob/master/src/fullnode.rs#L384

Yes, hardcoded small number sounds good. Consider even making it 1 and bumping back whatever's in that slot.

jackcmay commented 5 years ago

@greg The BPF loader is added as a sequence of transactions (SystemCreate, Write, .., Write, Finalize). What did you have in mind for the code location you suggested?

garious commented 5 years ago

Just if you wanted to populate an Account at startup instead of hardcoding it in the Bank.

mvines commented 5 years ago

How about building this into https://github.com/solana-labs/solana/blob/master/src/bin/genesis.rs? Other hard-coded native programs eventually could move out from bank.rs into genesis transactions as well (storage program, vote program, etc).

jackcmay commented 5 years ago

@mvines I'm planning to add the BpfLoader built-in here for now but we can move it later to genesis:

https://github.com/solana-labs/solana/blob/45cfa5b574eab362113f41d2fc573b0d1cf1bf0f/src/bank.rs#L197

    /// Create an Bank using a deposit.
    pub fn new_from_deposit(deposit: &Payment) -> Self {
        let bank = Self::default();
        {
            let mut accounts = bank.accounts.write().unwrap();
            let account = accounts.entry(deposit.to).or_insert_with(Account::default);
            Self::apply_payment(deposit, account);
        }
        {
            // Create Bpf Loader account
            let mut accounts = bank.accounts.write().unwrap();
            let account = accounts.entry(Pubkey::new(&BPF_LOADER_PROGRAM_ID)).or_insert_with(Account::default);
            account.tokens = 0;
            account.program_id = Pubkey::new(&BPF_LOADER_PROGRAM_ID);
            account.userdata = BPF_LOADER_NAME.as_bytes().to_vec();
            account.executable = true;
            account.loader_program_id = native_loader::id();
            println!("bpf account: {:#?}", account);
        }
        bank
    }
garious commented 5 years ago

process_transaction() should reject your tx if it's not after that register_id() in Bank::new()

jackcmay commented 5 years ago

I'm not making a tx, I'm inserting the bpf_loader() account directly into the accounts HashMap.

mvines commented 5 years ago

Just try to make it general enough to encourage others to use the same facility to add future pre-loaded programs (https://github.com/solana-labs/solana/pull/1552, wink wink nudge nudge) and to eventually boot programs from bank.rs hard coding

garious commented 5 years ago

I don't see how the genesis block solution would work for programs targeting the native loader. Can Windows execute the ELF?

jackcmay commented 5 years ago

Windows should be able to execute the ELF but that has not been tested at all.

jackcmay commented 5 years ago

@mvines Will work an a more generalized solution post Pillbox

mvines commented 5 years ago

@jackcmay want me to do the sdk side of this? (also cc: https://github.com/solana-labs/solana/issues/1418)

jackcmay commented 5 years ago

Addressed by #1573