This repository was archived by the owner on Jan 22, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4.9k
budget as separate contract and system call contract #1189
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
use budget::Budget; | ||
use chrono::prelude::{DateTime, Utc}; | ||
use payment_plan::{Payment, PaymentPlan, Witness}; | ||
use signature::Pubkey; | ||
use signature::Signature; | ||
|
||
/// The type of payment plan. Each item must implement the PaymentPlan trait. | ||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] | ||
pub enum Plan { | ||
/// The builtin contract language Budget. | ||
Budget(Budget), | ||
} | ||
|
||
// A proxy for the underlying DSL. | ||
impl PaymentPlan for Plan { | ||
fn final_payment(&self) -> Option<Payment> { | ||
match self { | ||
Plan::Budget(budget) => budget.final_payment(), | ||
} | ||
} | ||
|
||
fn verify(&self, spendable_tokens: i64) -> bool { | ||
match self { | ||
Plan::Budget(budget) => budget.verify(spendable_tokens), | ||
} | ||
} | ||
|
||
fn apply_witness(&mut self, witness: &Witness, from: &Pubkey) { | ||
match self { | ||
Plan::Budget(budget) => budget.apply_witness(witness, from), | ||
} | ||
} | ||
} | ||
|
||
/// A smart contract. | ||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] | ||
pub struct Contract { | ||
/// The number of tokens allocated to the `Plan` and any transaction fees. | ||
pub tokens: i64, | ||
pub plan: Plan, | ||
} | ||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] | ||
pub struct Vote { | ||
/// We send some gossip specific membership information through the vote to shortcut | ||
/// liveness voting | ||
/// The version of the CRDT struct that the last_id of this network voted with | ||
pub version: u64, | ||
/// The version of the CRDT struct that has the same network configuration as this one | ||
pub contact_info_version: u64, | ||
// TODO: add signature of the state here as well | ||
} | ||
|
||
/// An instruction to progress the smart contract. | ||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] | ||
pub enum Instruction { | ||
/// Declare and instanstansiate `Contract`. | ||
NewContract(Contract), | ||
|
||
/// Tell a payment plan acknowledge the given `DateTime` has past. | ||
ApplyTimestamp(DateTime<Utc>), | ||
|
||
/// Tell the payment plan that the `NewContract` with `Signature` has been | ||
/// signed by the containing transaction's `Pubkey`. | ||
ApplySignature(Signature), | ||
|
||
/// Vote for a PoH that is equal to the lastid of this transaction | ||
NewVote(Vote), | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
//! system smart contract | ||
|
||
use bank::Account; | ||
use bincode::deserialize; | ||
use signature::Pubkey; | ||
use transaction::Transaction; | ||
|
||
#[derive(Serialize, Deserialize, Debug, Clone)] | ||
pub enum SystemContract { | ||
/// Create a new account | ||
/// * Transaction::keys[0] - source | ||
/// * Transaction::keys[1] - new account key | ||
/// * tokens - number of tokens to transfer to the new account | ||
/// * space - memory to allocate if greater then zero | ||
/// * contract - the contract id of the new account | ||
CreateAccount { | ||
tokens: i64, | ||
space: u64, | ||
contract_id: Option<Pubkey>, | ||
}, | ||
/// Assign account to a contract | ||
/// * Transaction::keys[0] - account to assign | ||
Assign { contract_id: Pubkey }, | ||
/// Move tokens | ||
/// * Transaction::keys[0] - source | ||
/// * Transaction::keys[1] - destination | ||
Move { tokens: i64 }, | ||
} | ||
|
||
pub const SYSTEM_CONTRACT_ID: [u8; 32] = [0u8; 32]; | ||
|
||
impl SystemContract { | ||
pub fn check_id(contract_id: &Pubkey) -> bool { | ||
contract_id.as_ref() == SYSTEM_CONTRACT_ID | ||
} | ||
|
||
pub fn id() -> Pubkey { | ||
Pubkey::new(&SYSTEM_CONTRACT_ID) | ||
} | ||
pub fn get_balance(account: &Account) -> i64 { | ||
account.tokens | ||
} | ||
pub fn process_transaction(tx: &Transaction, accounts: &mut [Account]) { | ||
let syscall: SystemContract = deserialize(&tx.userdata).unwrap(); | ||
match syscall { | ||
SystemContract::CreateAccount { | ||
tokens, | ||
space, | ||
contract_id, | ||
} => { | ||
if !Self::check_id(&accounts[1].contract_id) { | ||
return; | ||
} | ||
if !Self::check_id(&accounts[0].contract_id) { | ||
return; | ||
} | ||
if space > 0 && !accounts[1].userdata.is_empty() { | ||
return; | ||
} | ||
accounts[0].tokens -= tokens; | ||
accounts[1].tokens += tokens; | ||
if let Some(id) = contract_id { | ||
accounts[1].contract_id = id; | ||
} | ||
accounts[1].userdata = vec![0; space as usize]; | ||
} | ||
SystemContract::Assign { contract_id } => { | ||
if !Self::check_id(&accounts[0].contract_id) { | ||
return; | ||
} | ||
accounts[0].contract_id = contract_id; | ||
} | ||
SystemContract::Move { tokens } => { | ||
//bank should be verifying correctness | ||
accounts[0].tokens -= tokens; | ||
accounts[1].tokens += tokens; | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instruction.rs is really just an implementation detail of budget, so (maybe later) this file could merge into budget.rs right?