Skip to content
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

Table rows v0.0001 #12

Merged
merged 2 commits into from
Jan 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ members = [
]

[workspace.package]
version = "0.1.1"
version = "0.1.2"
edition = "2021"
rust-version = "1.75"
authors = ["Jesse Schulman <[email protected]>"]
Expand Down
43 changes: 40 additions & 3 deletions crates/antelope/src/api/v1/chain.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
use crate::api::client::Provider;
use crate::api::v1::structs::{
ClientError, GetInfoResponse, ProcessedTransaction, ProcessedTransactionReceipt,
SendTransactionResponse, SendTransactionResponseError,
ClientError, GetInfoResponse, GetTableRowsParams, GetTableRowsResponse, ProcessedTransaction,
ProcessedTransactionReceipt, SendTransactionResponse, SendTransactionResponseError,
TableIndexType,
};
use crate::chain::block_id::BlockId;
use crate::chain::checksum::Checksum256;
use crate::chain::name::Name;
use crate::chain::time::TimePoint;
use crate::chain::transaction::{CompressionType, PackedTransaction, SignedTransaction};
use crate::chain::{Decoder, Packer};
use crate::name;
use crate::serializer::formatter::JSONObject;
use crate::serializer::formatter::{JSONObject, ValueTo};
use crate::util::hex_to_bytes;
use serde_json::Value;

pub struct ChainAPI {
Expand Down Expand Up @@ -103,4 +106,38 @@ impl ChainAPI {
},
})
}

pub fn get_table_rows<T: Packer + Default>(
&self,
params: GetTableRowsParams,
) -> Result<GetTableRowsResponse<T>, ClientError<()>> {
let result = self.provider.post(
String::from("/v1/chain/get_table_rows"),
Some(params.to_json()),
);

let json: Value = serde_json::from_str(result.unwrap().as_str()).unwrap();
let response_obj = JSONObject::new(json);
let more = response_obj.get_bool("more")?;
let next_key_str = response_obj.get_string("next_key")?;
let rows_value = response_obj.get_vec("rows")?;
let mut rows: Vec<T> = Vec::with_capacity(rows_value.len());
for encoded_row in rows_value {
let row_bytes_hex = &ValueTo::string(Some(encoded_row))?;
let row_bytes = hex_to_bytes(row_bytes_hex);
let mut decoder = Decoder::new(&row_bytes);
let mut row = T::default();
decoder.unpack(&mut row);
rows.push(row);
}

let next_key = TableIndexType::NAME(name!(next_key_str.as_str()));

Ok(GetTableRowsResponse {
rows,
more,
ram_payers: None,
next_key: Some(next_key),
})
}
}
58 changes: 58 additions & 0 deletions crates/antelope/src/api/v1/structs.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::chain::checksum::Checksum160;
use crate::chain::{
block_id::BlockId,
checksum::Checksum256,
Expand All @@ -6,6 +7,8 @@ use crate::chain::{
transaction::TransactionHeader,
varint::VarUint32,
};
use serde_json::{json, Value};
use std::collections::HashMap;

#[derive(Debug)]
pub enum ClientError<T> {
Expand Down Expand Up @@ -169,3 +172,58 @@ pub struct SendTransactionResponse {
pub transaction_id: String,
pub processed: ProcessedTransaction,
}

pub enum IndexPosition {
PRIMARY,
SECONDARY,
TERTIARY,
FOURTH,
FIFTH,
SIXTH,
SEVENTH,
EIGHTH,
NINTH,
TENTH,
}

pub enum TableIndexType {
NAME(Name),
UINT64(u64),
UINT128(u128),
FLOAT64(f64),
CHECKSUM256(Checksum256),
CHECKSUM160(Checksum160),
}

pub struct GetTableRowsParams {
pub code: Name,
pub table: Name,
pub scope: Option<Name>,
pub lower_bound: Option<TableIndexType>,
pub upper_bound: Option<TableIndexType>,
pub limit: Option<u32>,
pub reverse: Option<bool>,
pub index_position: Option<IndexPosition>,
pub show_payer: Option<bool>,
}

impl GetTableRowsParams {
pub fn to_json(&self) -> String {
let mut req: HashMap<&str, Value> = HashMap::new();
req.insert("json", Value::Bool(false));
req.insert("code", Value::String(self.code.to_string()));
req.insert("table", Value::String(self.table.to_string()));

let scope = self.scope.unwrap_or(self.code);
req.insert("scope", Value::String(scope.to_string()));

json!(req).to_string()
}
}

pub struct GetTableRowsResponse<T> {
pub rows: Vec<T>,
pub more: bool,
pub ram_payers: Option<Vec<Name>>,
pub next_key: Option<TableIndexType>,
}
28 changes: 28 additions & 0 deletions crates/antelope/src/serializer/formatter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,26 @@ impl ValueTo {
Ok(value.as_str().unwrap().to_string())
}

pub fn bool(v: Option<&Value>) -> Result<bool, EncodingError> {
check_some(v, "bool")?;
let value = v.unwrap();
if !value.is_boolean() {
return Err(EncodingError::new("Value is not bool".into()));
}

Ok(value.as_bool().unwrap())
}

pub fn vec(v: Option<&Value>) -> Result<&Vec<Value>, EncodingError> {
check_some(v, "Vec")?;
let value = v.unwrap();
if !value.is_array() {
return Err(EncodingError::new("Value is not Vec".into()));
}

Ok(value.as_array().unwrap())
}

pub fn hex_bytes(v: Option<&Value>) -> Result<Vec<u8>, EncodingError> {
let value = Self::string(v)?;
return Ok(hex_to_bytes(value.as_str()));
Expand Down Expand Up @@ -84,6 +104,14 @@ impl JSONObject {
ValueTo::string(self.value.get(property))
}

pub fn get_bool(&self, property: &str) -> Result<bool, EncodingError> {
ValueTo::bool(self.value.get(property))
}

pub fn get_vec(&self, property: &str) -> Result<&Vec<Value>, EncodingError> {
ValueTo::vec(self.value.get(property))
}

pub fn get_hex_bytes(&self, property: &str) -> Result<Vec<u8>, EncodingError> {
ValueTo::hex_bytes(self.value.get(property))
}
Expand Down
58 changes: 57 additions & 1 deletion crates/antelope/tests/client.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use antelope::api::client::APIClient;
use antelope::api::v1::structs::ClientError;
use antelope::api::v1::structs::{ClientError, GetTableRowsParams};
use antelope::chain::asset::Asset;
use antelope::chain::block_id::BlockId;
use antelope::chain::name::Name;
use antelope::name;
use antelope::serializer::{Decoder, Encoder, Packer};
use antelope::util::hex_to_bytes;
use antelope::StructPacker;
mod utils;
use crate::utils::mock_provider;
use utils::mock_provider::MockProvider;
Expand Down Expand Up @@ -82,3 +84,57 @@ fn chain_send_transaction() {
}
}
}

#[test]
pub fn chain_get_table_rows() {
#[derive(StructPacker, Default)]
struct UserRow {
balance: Asset,
}

let mock_provider = MockProvider {};
let client = APIClient::custom_provider(Box::new(mock_provider)).unwrap();
//let client = APIClient::default_provider(String::from("https://testnet.telos.caleos.io")).unwrap();

let res1 = client
.v1_chain
.get_table_rows::<UserRow>(GetTableRowsParams {
code: name!("eosio.token"),
table: name!("accounts"),
scope: Some(name!("corecorecore")),
lower_bound: None,
upper_bound: None,
limit: None,
reverse: None,
index_position: None,
show_payer: None,
})
.unwrap();

assert_eq!(res1.rows.len(), 1, "Should get 1 row back");
assert_eq!(
res1.rows[0].balance.symbol().code().to_string(),
"TLOS",
"Should get TLOS symbol back"
);

// const res1 = await eos.v1.chain.get_table_rows({
// code: 'fuel.gm',
// table: 'users',
// type: User,
// limit: 1,
// })
// assert.equal(res1.rows[0].account instanceof Name, true)
// assert.equal(res1.more, true)
// assert.equal(String(res1.rows[0].account), 'aaaa')
// const res2 = await eos.v1.chain.get_table_rows({
// code: 'fuel.gm',
// table: 'users',
// type: User,
// limit: 2,
// lower_bound: res1.next_key,
// })
// assert.equal(String(res2.rows[0].account), 'atomichub')
// assert.equal(String(res2.next_key), 'boidservices')
// assert.equal(Number(res2.rows[1].balance).toFixed(6), (0.02566).toFixed(6))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"rows":["ccd8f5050000000004544c4f53000000"],"more":false,"next_key":""}
Loading