-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Initial WIP #31
Open
Arkweid
wants to merge
2
commits into
master
Choose a base branch
from
add-transactions
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Initial WIP #31
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
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
This file contains 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 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 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 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 |
---|---|---|
@@ -1,7 +1,6 @@ | ||
#![allow(dead_code)] | ||
|
||
mod error; | ||
mod keypair; | ||
mod strkey; | ||
mod error; | ||
|
||
pub use self::keypair::from_secret_seed; |
This file contains 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 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,114 @@ | ||
use super::{db_conn, schema::accounts}; | ||
use diesel::prelude::*; | ||
|
||
// https://www.stellar.org/developers/guides/concepts/accounts.html | ||
|
||
// TODO: We should take base reserve from ledger header | ||
pub const BASE_RESERVE: i64 = 5000000; | ||
|
||
#[derive(Identifiable, Queryable, Debug)] | ||
#[primary_key(accountid)] | ||
pub struct Account { | ||
/// The public key that was first used to create the account. You can replace the key used for signing the account’s transactions with a different public key, but the original account ID will always be used to identify the account. | ||
pub accountid: String, | ||
/// The number of lumens held by the account. The balance is denominated in 1/10,000,000th of a lumen, the smallest divisible unit of a lumen. | ||
pub balance: i64, | ||
/// The current transaction sequence number of the account. This number starts equal to the ledger number at which the account was created. | ||
pub seqnum: i64, | ||
/// Number of other entries the account owns. This number is used to calculate the account’s minimum balance. | ||
pub numsubentries: i32, | ||
/// (optional) Account designated to receive inflation. Every account with a balance of at least 100 XLM can vote to send inflation to a destination account. | ||
pub inflationdest: Option<String>, | ||
/// A domain name that can optionally be added to the account. Clients can look up a stellar.toml from this domain. This should be in the format of a fully qualified domain name such as example.com. | ||
/// The federation protocol can use the home domain to look up more details about a transaction’s memo or address details about an account. For more on federation, see the federation guide. | ||
pub homedomain: String, | ||
/// Operations have varying levels of access. This field specifies thresholds for low-, medium-, and high-access levels, as well as the weight of the master key. For more info, see multi-sig. | ||
pub thresholds: String, | ||
/// Currently there are three flags, used by issuers of assets. | ||
/// - Authorization required (0x1): Requires the issuing account to give other accounts permission before they can hold the issuing account’s credit. | ||
/// - Authorization revocable (0x2): Allows the issuing account to revoke its credit held by other accounts. | ||
/// - Authorization immutable (0x4): If this is set then none of the authorization flags can be set and the account can never be deleted. | ||
pub flags: i32, | ||
/// updated_at field | ||
pub lastmodified: i32, | ||
/// Starting in protocol version 10, each account also tracks its lumen liabilities. Buying liabilities equal the total amount of lumens offered to buy aggregated over all offers owned by this account, and selling liabilities equal the total amount of lumens offered to sell aggregated over all offers owned by this account. An account must always have balance sufficiently above the minimum reserve to satisfy its lumen selling liabilities, and a balance sufficiently below the maximum to accomodate its lumen buying liabilities | ||
pub buyingliabilities: i64, | ||
pub sellingliabilities: i64, | ||
/// Used for multi-sig. This field lists other public keys and their weights, which can be used to authorize transactions for this account. | ||
pub signers: Option<String>, | ||
} | ||
|
||
type Result<T> = std::result::Result<T, diesel::result::Error>; | ||
|
||
impl Account { | ||
pub fn all() -> Result<Vec<Account>> { | ||
use self::accounts::dsl::*; | ||
|
||
accounts.load::<Account>(&*db_conn()) | ||
} | ||
|
||
pub fn create(accountid: String) -> Result<usize> { | ||
let new_account = NewAccount::new(accountid); | ||
diesel::insert_into(accounts::table) | ||
.values(&new_account) | ||
.execute(&*db_conn()) | ||
} | ||
|
||
pub fn get(g_accountid: &str) -> Result<Account> { | ||
use self::accounts::dsl::*; | ||
|
||
accounts | ||
.filter(accountid.eq(g_accountid)) | ||
.first::<Account>(&*db_conn()) | ||
} | ||
|
||
pub fn delete(g_accountid: &str) -> Result<usize> { | ||
use self::accounts::dsl::*; | ||
|
||
diesel::delete(accounts.filter(accountid.eq(g_accountid))).execute(&*db_conn()) | ||
} | ||
|
||
// TODO: this should take base reserve from particular | ||
// ledger header into account | ||
// TODO: consider ledger version lower than 8, formulae was | ||
// different back then | ||
pub fn spendable_balance(&self) -> i64 { | ||
self.balance - ((2 + i64::from(self.numsubentries)) * BASE_RESERVE) | ||
} | ||
} | ||
|
||
#[derive(Insertable)] | ||
#[table_name = "accounts"] | ||
pub struct NewAccount { | ||
pub accountid: String, | ||
pub balance: i64, | ||
pub seqnum: i64, | ||
pub numsubentries: i32, | ||
pub inflationdest: Option<String>, | ||
pub homedomain: String, | ||
pub thresholds: String, | ||
pub flags: i32, | ||
pub lastmodified: i32, | ||
pub buyingliabilities: i64, | ||
pub sellingliabilities: i64, | ||
pub signers: Option<String>, | ||
} | ||
|
||
impl NewAccount { | ||
pub fn new(accountid: String) -> Self { | ||
NewAccount { | ||
accountid, | ||
balance: 0, | ||
seqnum: 0, // TODO: This number starts equal to the ledger number at which the account was created | ||
numsubentries: 0, | ||
inflationdest: None, | ||
homedomain: String::from("example.com"), | ||
thresholds: String::from(""), | ||
flags: 1, | ||
lastmodified: 0, | ||
buyingliabilities: 0, | ||
sellingliabilities: 0, | ||
signers: None, | ||
} | ||
} | ||
} |
This file contains 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 |
---|---|---|
@@ -1,4 +1,5 @@ | ||
#![allow(dead_code, unused_must_use)] | ||
|
||
pub(crate) mod peer; | ||
pub(crate) mod account; | ||
pub(crate) use super::{db_conn, schema, CONFIG}; |
This file contains 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 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 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 |
---|---|---|
|
@@ -12,6 +12,7 @@ mod network; | |
mod overlay; | ||
mod schema; | ||
mod scp; | ||
mod stellar_base; | ||
mod xdr; | ||
|
||
fn main() { | ||
|
This file contains 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 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 @@ | ||
pub mod strkey; |
This file contains 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 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,77 @@ | ||
use crate::xdr; | ||
use crate::database::{db_conn, Account, BASE_RESERVE}; | ||
use crate::stellar_base::strkey; | ||
use super::utils; | ||
// TODO: I believe, everything should work without using `prelude`. But it doesn't | ||
use diesel::prelude::*; | ||
use diesel::result::Error::NotFound; | ||
|
||
pub(crate) fn create_account_operation(source_account: Option<xdr::AccountId>, account_operation: xdr::CreateAccountOp) -> xdr::CreateAccountResultCode { | ||
let dest_account_id = strkey::encode_ed25519_public_key(account_operation.destination).unwrap(); | ||
|
||
if account_operation.starting_balance < BASE_RESERVE { | ||
xdr::CreateAccountResultCode::CreateAccountLowReserve | ||
} else if Account::get(&dest_account_id).is_ok() { | ||
xdr::CreateAccountResultCode::CreateAccountAlreadyExist | ||
} else { | ||
match source_account { | ||
Some(public_key) => { | ||
let source_account_id = strkey::encode_ed25519_public_key(public_key).unwrap(); | ||
|
||
match Account::get(&source_account_id) { | ||
Ok(account) => { | ||
if account.spendable_balance() < account_operation.starting_balance { | ||
xdr::CreateAccountResultCode::CreateAccountUnderfunded | ||
} else { | ||
// Actually apply operation | ||
use crate::schema::accounts::dsl::balance; | ||
|
||
let new_balance = utils::add_balance(&account, account_operation.starting_balance).unwrap(); | ||
diesel::update(&account) | ||
.set(balance.eq(new_balance)) | ||
.execute(&*db_conn()) | ||
.unwrap(); | ||
|
||
xdr::CreateAccountResultCode::CreateAccountSuccess | ||
} | ||
}, | ||
Err(e) => { | ||
match e { | ||
NotFound => { | ||
xdr::CreateAccountResultCode::CreateAccountMalformed | ||
}, | ||
_ => { | ||
// TODO: What do we do in this case? | ||
xdr::CreateAccountResultCode::CreateAccountMalformed | ||
} | ||
} | ||
} | ||
} | ||
} | ||
None => { | ||
xdr::CreateAccountResultCode::CreateAccountUnderfunded | ||
} | ||
} | ||
} | ||
} | ||
|
||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::{xdr}; | ||
use crate::factories::internal_xdr; | ||
|
||
#[test] | ||
fn test_account_operation_with_zero_balance() { | ||
let source_account = internal_xdr::random_public_key(); | ||
|
||
let operation = xdr::CreateAccountOp { | ||
destination: internal_xdr::random_public_key(), | ||
starting_balance: 0, | ||
}; | ||
|
||
let result = super::create_account_operation(Some(source_account), operation); | ||
|
||
assert_eq!(result, xdr::CreateAccountResultCode::CreateAccountLowReserve); | ||
} | ||
} |
This file contains 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,21 @@ | ||
// pub(crate) use crate::config::CONFIG; | ||
// pub(crate) use crate::crypto; | ||
// pub(crate) use crate::network::Network; | ||
use crate::xdr; | ||
|
||
mod create_account_operation; | ||
mod utils; | ||
|
||
use create_account_operation::create_account_operation; | ||
// pub(crate) use lazy_static::lazy_static; | ||
|
||
// pub(crate) use crate::database::models::account; | ||
|
||
pub fn do_apply(operation: xdr::Operation) { | ||
match operation.body { | ||
xdr::OperationBody::CreateAccountOp(acccount_operation) => { | ||
create_account_operation(operation.source_account, acccount_operation); | ||
}, | ||
_ => {} | ||
} | ||
} |
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.
@Arkweid why do we have
source_account
as anOption
here?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.
Well, who is the
Source Account
when I will try to create fresh account for myself?