Skip to content

Commit

Permalink
Add token & update supply changes & balance_changes
Browse files Browse the repository at this point in the history
  • Loading branch information
DenisCarriere committed Nov 9, 2024
1 parent fe1af9d commit b6469e7
Show file tree
Hide file tree
Showing 6 changed files with 169 additions and 112 deletions.
14 changes: 9 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,14 @@ graph:
info:
substreams info

.PHONY: run
run:
substreams run -e eos.substreams.pinax.network:443 graph_out -s -10000

.PHONY: gui
gui:
substreams gui -e eos.substreams.pinax.network:443 graph_out -s -10000
substreams gui substreams.yaml -e eos.substreams.pinax.network:443 map_events -s -1000 -t 0

.PHONY: parquet
parquet:
substreams-sink-files run eos.substreams.pinax.network:443 substreams.yaml map_events '.' 2: --encoder parquet

.PHONY: schema
schema:
substreams-sink-files tools parquet schema substreams.yaml map_events
8 changes: 8 additions & 0 deletions proto/v1/eosio.token.proto
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,10 @@ message BalanceChange {
google.protobuf.Timestamp timestamp = 14;
string block_hash = 15;
string block_date = 16;

// token
string token = 17; // ExtendedSymbol
string operation = 18; // db_op::Operation
}

message SupplyChange {
Expand Down Expand Up @@ -169,4 +173,8 @@ message SupplyChange {
google.protobuf.Timestamp timestamp = 14;
string block_hash = 15;
string block_date = 16;

// token
string token = 17; // ExtendedSymbol
string operation = 18; // db_op::Operation
}
106 changes: 55 additions & 51 deletions src/balance_changes.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
use crate::{abi, BalanceChange};
use antelope::{Asset, Name, Symbol, SymbolCode};
use crate::BalanceChange;
use antelope::{Asset, ExtendedSymbol, Name};
use substreams::{log, pb::substreams::Clock};
use substreams_antelope::decoder::decode;
use substreams_antelope::Block;

use crate::utils;
use crate::utils::{self, parse_json_asset};

pub fn collect_balance_changes(clock: &Clock, block: &Block) -> Vec<BalanceChange> {
block
Expand All @@ -15,78 +14,83 @@ pub fn collect_balance_changes(clock: &Clock, block: &Block) -> Vec<BalanceChang
return None;
}

let old_data = decode::<abi::types::Account>(&db_op.old_data_json).ok();
let new_data = decode::<abi::types::Account>(&db_op.new_data_json).ok();

let old_balance =
old_data
.as_ref()
.and_then(|data| match data.balance.parse::<Asset>() {
Ok(asset) => Some(asset),
Err(e) => {
log::info!(
"Error parsing old balance asset in trx {}: {:?}",
trx.id,
e
);
None
}
});
let new_balance =
new_data
.as_ref()
.and_then(|data| match data.balance.parse::<Asset>() {
Ok(asset) => Some(asset),
Err(e) => {
log::info!(
"Error parsing new balance asset in trx {}: {:?}",
trx.id,
e
);
None
}
});
// decoded
let old_balance = parse_json_asset(&db_op.old_data_json, "balance");
let new_balance = parse_json_asset(&db_op.new_data_json, "balance");

// no valid Accounts
if old_balance.is_none() && new_balance.is_none() {
return None;
}

let raw_primary_key = Name::from(db_op.primary_key.as_str()).value;
let symcode = SymbolCode::from(raw_primary_key);
let precision = new_balance
.unwrap_or_else(|| old_balance.unwrap())
.symbol
.precision();
let sym = Symbol::from_precision(symcode, precision);
let balance = new_balance.unwrap_or_else(|| Asset::from_amount(0, sym));
let balance_delta = balance.amount
- old_balance
.unwrap_or_else(|| Asset::from_amount(0, sym))
.amount;
// token contract & account
let contract = Name::from(db_op.code.as_str());
let account = Name::from(db_op.scope.as_str());

// ignore invalid contract or account
if contract.value == 0 || account.value == 0 {
log::info!(
"Invalid contract or account in trx {}: contract: {}, account: {}",
trx.id,
contract,
account
);
return None;
}

// ignore mismatched balances
if old_balance.is_some() && new_balance.is_some() {
if old_balance.unwrap().symbol != new_balance.unwrap().symbol {
log::info!(
"Mismatched balance in trx {}: old_balance: {:?}, new_balance: {:?}",
trx.id,
old_balance,
new_balance
);
return None;
}
}

// fields derived from old_balance or new_balance
let sym = old_balance
.or(new_balance)
.as_ref()
.expect("missing old_balance or new_balance")
.symbol;
let token = ExtendedSymbol::from_extended(sym, contract);
let zero = Asset::from_amount(0, sym);
let balance = new_balance.as_ref().unwrap_or(&zero);
let old_balance = old_balance.as_ref().unwrap_or(&zero);
let balance_delta = balance.amount - old_balance.amount;

Some(BalanceChange {
// trace information
trx_id: trx.id.clone(),
action_index: db_op.action_index,

// contract & scope
contract: db_op.code.clone(),
symcode: symcode.to_string(),
contract: contract.to_string(),
symcode: sym.code().to_string(),

// payload
account: db_op.scope.clone(),
account: account.to_string(),
balance: balance.to_string(),
balance_delta,

// extras
precision: precision.into(),
precision: sym.precision().into(),
amount: balance.amount,
value: utils::to_value(&balance),

// block
block_num: clock.number,
timestamp: clock.timestamp,
block_hash: clock.id.clone(),
block_date: utils::to_date(&clock),

// token (ex: "4,[email protected]")
token: token.to_string(),
operation: db_op.operation().as_str_name().to_string(),
})
})
})
Expand Down
16 changes: 16 additions & 0 deletions src/pb/antelope.eosio.token.v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,14 @@ pub struct BalanceChange {
pub block_hash: ::prost::alloc::string::String,
#[prost(string, tag="16")]
pub block_date: ::prost::alloc::string::String,
/// token
///
/// ExtendedSymbol
#[prost(string, tag="17")]
pub token: ::prost::alloc::string::String,
/// db_op::Operation
#[prost(string, tag="18")]
pub operation: ::prost::alloc::string::String,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
Expand Down Expand Up @@ -241,5 +249,13 @@ pub struct SupplyChange {
pub block_hash: ::prost::alloc::string::String,
#[prost(string, tag="16")]
pub block_date: ::prost::alloc::string::String,
/// token
///
/// ExtendedSymbol
#[prost(string, tag="17")]
pub token: ::prost::alloc::string::String,
/// db_op::Operation
#[prost(string, tag="18")]
pub operation: ::prost::alloc::string::String,
}
// @@protoc_insertion_point(module)
103 changes: 51 additions & 52 deletions src/supply_changes.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
use crate::{abi, SupplyChange};
use antelope::{Asset, Name, Symbol, SymbolCode};
use crate::{utils::parse_json_name, SupplyChange};
use antelope::{Asset, ExtendedSymbol, Name};
use substreams::{log, pb::substreams::Clock};
use substreams_antelope::decoder::decode;
use substreams_antelope::Block;

use crate::utils;
use crate::utils::{self, parse_json_asset};

pub fn collect_supply_changes(clock: &Clock, block: &Block) -> Vec<SupplyChange> {
block
Expand All @@ -14,82 +13,82 @@ pub fn collect_supply_changes(clock: &Clock, block: &Block) -> Vec<SupplyChange>
if db_op.table_name != "stat" {
return None;
}
// token contract
let contract = Name::from(db_op.code.as_str());

let old_data = decode::<abi::types::CurrencyStats>(&db_op.old_data_json).ok();
let new_data = decode::<abi::types::CurrencyStats>(&db_op.new_data_json).ok();

let old_supply =
old_data
.as_ref()
.and_then(|data| match data.supply.parse::<Asset>() {
Ok(asset) => Some(asset),
Err(e) => {
log::info!(
"Error parsing old supply asset in trx {}: {:?}",
trx.id,
e
);
None
}
});
// ignore invalid contract or account
if contract.value == 0 {
log::info!("Invalid contract in trx {}: contract: {}", trx.id, contract,);
return None;
}

let new_supply =
new_data
.as_ref()
.and_then(|data| match data.supply.parse::<Asset>() {
Ok(asset) => Some(asset),
Err(e) => {
log::info!(
"Error parsing new supply asset in trx {}: {:?}",
trx.id,
e
);
None
}
});
// parse Assets
let old_supply = parse_json_asset(&db_op.old_data_json, "supply");
let new_supply = parse_json_asset(&db_op.new_data_json, "supply");
let new_max_supply = parse_json_asset(&db_op.new_data_json, "max_supply");
let new_issuer = parse_json_name(&db_op.new_data_json, "issuer");

// no valid Assets
if old_supply.is_none() && new_supply.is_none() {
return None;
}

let symcode = SymbolCode::from(Name::from(db_op.primary_key.as_str()).value);
let precision = new_supply
.unwrap_or_else(|| old_supply.unwrap())
.symbol
.precision();
let sym = Symbol::from_precision(symcode, precision);
let supply = new_supply.unwrap_or_else(|| Asset::from_amount(0, sym));
let supply_delta = supply.amount
- old_supply
.unwrap_or_else(|| Asset::from_amount(0, sym))
.amount;
// ignore mismatched supply
if old_supply.is_some() && new_supply.is_some() {
if old_supply.unwrap().symbol != new_supply.unwrap().symbol {
log::info!(
"Mismatched supply in trx {}: old_supply: {:?}, new_supply: {:?}",
trx.id,
old_supply,
new_supply
);
return None;
}
}

let data = new_data.unwrap_or_else(|| old_data.unwrap());
// fields derived from old_balance or new_balance
let sym = old_supply
.or(new_supply)
.as_ref()
.expect("missing old_supply or new_supply")
.symbol;
let token = ExtendedSymbol::from_extended(sym, contract);
let zero = Asset::from_amount(0, sym);
let old_supply = old_supply.as_ref().unwrap_or(&zero);
let supply = new_supply.as_ref().unwrap_or(&zero);
let supply_delta = supply.amount - old_supply.amount;
let max_supply = new_max_supply.as_ref().unwrap_or(&zero);
let issuer = new_issuer.unwrap_or(Name::new());

Some(SupplyChange {
// trace information
trx_id: trx.id.clone(),
action_index: db_op.action_index,

// contract & scope
contract: db_op.code.clone(),
symcode: symcode.to_string(),
contract: contract.to_string(),
symcode: sym.code().to_string(),

// payload
issuer: data.issuer,
max_supply: data.max_supply,
issuer: issuer.to_string(),
max_supply: max_supply.to_string(),
supply: supply.to_string(),
supply_delta,

// extras
precision: precision.into(),
precision: sym.precision().into(),
amount: supply.amount,
value: utils::to_value(&supply),

// block
block_num: clock.number,
timestamp: clock.timestamp,
block_hash: clock.id.clone(),
block_date: utils::to_date(&clock),

// token (ex: "4,[email protected]")
token: token.to_string(),
operation: db_op.operation().as_str_name().to_string(),
})
})
})
Expand Down
Loading

0 comments on commit b6469e7

Please sign in to comment.