From 6c5f252f9b68ad3b96006ed0f06c8f06d13094bd Mon Sep 17 00:00:00 2001 From: Brian Johnson Date: Mon, 20 Nov 2017 15:47:10 -0600 Subject: [PATCH] Adding account balance API. --- contracts/eoslib/account.h | 36 +++++++++++++ contracts/eoslib/account.hpp | 81 ++++++++++++++++++++++++++++++ libraries/chain/wasm_interface.cpp | 62 +++++++++++++++++++++++ 3 files changed, 179 insertions(+) create mode 100644 contracts/eoslib/account.h create mode 100644 contracts/eoslib/account.hpp diff --git a/contracts/eoslib/account.h b/contracts/eoslib/account.h new file mode 100644 index 000000000..8a83f0627 --- /dev/null +++ b/contracts/eoslib/account.h @@ -0,0 +1,36 @@ +/** + * @file + * @copyright defined in eos/LICENSE.txt + */ +#pragma once + +#include + +/** + * @defgroup accountcapi Account API + * @brief Define API for querying account data + * @ingroup contractdev + */ + +extern "C" { + /** + * @brief Return the balance for the provided account + * + * @param balance - a pointer to a range of memory to store balance data + * @param len - length of the range of memory to store balance data + * + * @pre data is a valid pointer to a range of memory at least datalen bytes long + * @pre data is a pointer to a balance object + * @pre *((uint64_t*)data) stores the primary key + * + * Example: + * @code + * balance b; + * b.account = n(myaccount); + * balance(b, sizeof(balance)); + * @endcode + */ + + void account_balance_get( void* balance, uint32_t len ); + ///@ } accountcapi +} diff --git a/contracts/eoslib/account.hpp b/contracts/eoslib/account.hpp new file mode 100644 index 000000000..0f543d185 --- /dev/null +++ b/contracts/eoslib/account.hpp @@ -0,0 +1,81 @@ +/** +* @file token.hpp +* @copyright defined in eos/LICENSE.txt +* @brief Defines types and ABI for standard token messages and database tables +* +*/ +#pragma once +#include +#include + + +namespace eosio { namespace account { + /** + * @defgroup tokens Token API + * @brief Defines the ABI for interfacing with standard-compatible token messages and database tables. + * @ingroup contractdev + * + * @{ + */ + +/** +* @struct eosio::account_balance (must match account_balance defined in wasm_interface.cpp) +* @brief The binary structure expected and populated by native balance function. +* @ingroup tokens +* +* @details +* Example: +* @code +* account_balance test1_balance; +* test1_balance.account = N(test1); +* if (account_api::get(test1_balance)) +* { +* eos::print("test1 balance=", test1_balance.eos_balance, "\n"); +* } +* @endcode +* @{ +*/ +struct PACKED (account_balance) { + /** + * Name of the account who's balance this is + * @brief Name of the account who's balance this is + */ + account_name account; + + /** + * Balance for this account + * @brief Balance for this account + */ + asset eos_balance; + + /** + * Staked balance for this account + * @brief Staked balance for this account + */ + asset staked_balance; + + /** + * Unstaking balance for this account + * @brief Unstaking balance for this account + */ + asset unstaking_balance; + + /** + * Time at which last unstaking occurred for this account + * @brief Time at which last unstaking occurred for this account + */ + time last_unstaking_time; +}; + +/** + * Retrieve a populated balance structure + * @param account_balance stream to write + * @ret true if account's balance is found + */ + +bool get(account_balance& b) +{ + return account_balance(&b, sizeof(account_balance)); +} + +} } diff --git a/libraries/chain/wasm_interface.cpp b/libraries/chain/wasm_interface.cpp index b59de4a50..6afd93ae5 100644 --- a/libraries/chain/wasm_interface.cpp +++ b/libraries/chain/wasm_interface.cpp @@ -17,6 +17,8 @@ #include "IR/Validate.h" #include #include +#include +#include #include #include #include @@ -46,6 +48,42 @@ namespace eosio { namespace chain { U32 _num_bytes; }; + // account.h/hpp expected account API balance interchange format + // must match account.hpp account_balance definition + PACKED_STRUCT( + struct account_balance + { + /** + * Name of the account who's balance this is + * @brief Name of the account who's balance this is + */ + account_name account; + + /** + * Balance for this account + * @brief Balance for this account + */ + asset eos_balance; + + /** + * Staked balance for this account + * @brief Staked balance for this account + */ + asset staked_balance; + + /** + * Unstaking balance for this account + * @brief Unstaking balance for this account + */ + asset unstaking_balance; + + /** + * Time at which last unstaking occurred for this account + * @brief Time at which last unstaking occurred for this account + */ + time last_unstaking_time; + }) + wasm_interface::wasm_interface() { } @@ -688,6 +726,30 @@ DEFINE_INTRINSIC_FUNCTION2(env,printhex,printhex,none,i32,data,i32,datalen) { DEFINE_INTRINSIC_FUNCTION1(env,free,free,none,i32,ptr) { } +DEFINE_INTRINSIC_FUNCTION2(env,account_balance_get,account_balance_get,i32,i32,charptr,i32,len) { + auto& wasm = wasm_interface::get(); + auto mem = wasm.current_memory; + + const uint32_t account_balance_size = sizeof(account_balance); + FC_ASSERT( len == account_balance_size, "passed in len ${len} is not equal to the size of an account_balance struct == ${real_len}", ("len",len)("real_len",account_balance_size) ); + + account_balance& total_balance = memoryRef( mem, charptr ); + + auto& db = wasm.current_apply_context->db; + auto* balance = db.find< balance_object,by_owner_name >( total_balance.account ); + auto* staked_balance = db.find( total_balance.account ); + + if (balance == nullptr || staked_balance == nullptr) + return false; + + total_balance.eos_balance = asset(balance->balance, EOS_SYMBOL); + total_balance.staked_balance = asset(staked_balance->staked_balance); + total_balance.unstaking_balance = asset(staked_balance->unstaking_balance); + total_balance.last_unstaking_time = staked_balance->last_unstaking_time; + + return true; +} + wasm_interface& wasm_interface::get() { static wasm_interface* wasm = nullptr; if( !wasm ) -- GitLab