Skip to content

Commit

Permalink
Merge pull request #2 from encointer/ab/transaction-log-for-native
Browse files Browse the repository at this point in the history
transaction log for native
  • Loading branch information
brenzi authored Sep 29, 2024
2 parents 6ab41a9 + 92f2f28 commit 084809d
Show file tree
Hide file tree
Showing 6 changed files with 294 additions and 32 deletions.
55 changes: 54 additions & 1 deletion api/accounting.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ import {
getCumulativeRewardsData,
getFrequencyOfAttendance,
getTransactionActivityLog,
getSankeyReport,
getSankeyReport, generateNativeTxnLog,
} from "../data.js";
import { parseEncointerBalance } from "@encointer/types";
import {
gatherNativeTransactionData,
gatherTransactionData,
getBlockNumberByTimestamp,
} from "../graphQl.js";
Expand Down Expand Up @@ -396,6 +397,58 @@ accounting.get("/transaction-log", async function (req, res, next) {
}
});

/**
* @swagger
* /v1/accounting/native-transaction-log:
* get:
* description: Retrieve transaction log for a specified account, only native token, between start and end
* parameters:
* - in: query
* name: start
* required: true
* description: Timestamp
* schema:
* type: string
* - in: query
* name: end
* required: true
* description: Timestamp
* schema:
* type: string
* - in: query
* name: account
* required: true
* description: AccountId
* schema:
* type: string
* tags:
* - accounting
* responses:
* '200':
* description: Success
* '403':
* description: Permission denied
*/
accounting.get("/native-transaction-log", async function (req, res, next) {
try {
const query = req.query;
const account = query.account;
const start = parseInt(query.start);
const end = parseInt(query.end);

const [incoming, incomingDrips, incomingXcm, outgoing, outgoingXcm] = await gatherNativeTransactionData(
start,
end,
account,
);

const txnLog = generateNativeTxnLog(incoming, incomingDrips, incomingXcm, outgoing, outgoingXcm);

res.send(JSON.stringify(txnLog));
} catch (e) {
next(e);
}
});

/**
* @swagger
Expand Down
109 changes: 95 additions & 14 deletions data.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import {
getReputableRegistrations,
getAllTransfers,
} from "./graphQl.js";
import { getMonthName, mapRescueCids, parseCid } from "./util.js";
import {getMonthName, mapRescueCids, parseCid, toNativeDecimal} from "./util.js";
import BN from "bn.js";

function canBeCached(month, year) {
return monthIsOver(month, year);
Expand Down Expand Up @@ -80,7 +81,7 @@ export async function gatherAccountingOverview(
i
);
data.push(accountingData);
db.insertIntoAccountDataCache(
await db.insertIntoAccountDataCache(
account,
year,
i,
Expand Down Expand Up @@ -347,8 +348,7 @@ export async function gatherRewardsData(api, cid) {
([key]) => parseInt(key) < currentCindex - 1
)
);
db.insertIntoRewardsDataCache(cid, dataToBeCached);

await db.insertIntoRewardsDataCache(cid, dataToBeCached);
return result;
}

Expand Down Expand Up @@ -376,6 +376,85 @@ export function generateTxnLog(incoming, outgoing, issues) {
return txnLog;
}

export function generateNativeTxnLog(incoming, incomingDrips, incomingXcm, outgoing, outgoingXcm) {
const incomingLog = incoming.map((e) => ({
blockNumber: e.blockNumber.toString(),
timestamp: e.timestamp.toString(),
counterParty: e.signer.Id,
amount: toNativeDecimal(e.args.value),
}));
const incomingDripsLog = incomingDrips.map((e) => {
return {
blockNumber: e.blockNumber.toString(),
timestamp: e.timestamp.toString(),
counterParty: e.data[0],
amount: toNativeDecimal(e.data[2]),
}
});
const incomingXcmLog = incomingXcm.map((e) => {
return {
blockNumber: e.blockNumber.toString(),
timestamp: e.timestamp.toString(),
counterParty: "XCMteleporter",
amount: toNativeDecimal(e.data.amount),
}
});
const outgoingLog = outgoing.map((e) => ({
blockNumber: e.blockNumber.toString(),
timestamp: e.timestamp.toString(),
counterParty: e.args.dest.Id,
amount: -1 * toNativeDecimal(e.args.value),
}));
const outgoingXcmLog = outgoingXcm.map((e) => {
let amount;
if (e.args.assets.V1) {
amount = toNativeDecimal(e.args.assets.V1[0].fun.Fungible);
} else if (e.args.assets.V2) {
amount = toNativeDecimal(e.args.assets.V2[0].fun.Fungible);
} else if (e.args.assets.V3) {
amount = toNativeDecimal(e.args.assets.V3[0].fun.Fungible);
} else if (e.args.assets.V4) {
amount = toNativeDecimal(e.args.assets.V4[0].fun.Fungible);
} else {
amount = 0;
}
let dest;
if (e.args.dest.V1) {
if (e.args.dest.V1.parents === "1") {
dest = (e.args.dest.V1.interior === "Here") ? "Relay" : "Para";
} else { dest = "unknown"; }
} else if (e.args.dest.V2) {
if (e.args.dest.V2.parents === "1") {
dest = (e.args.dest.V2.interior === "Here") ? "Relay" : "Para";
} else { dest = "unknown"; }
} else if (e.args.dest.V3) {
if (e.args.dest.V3.parents === "1") {
dest = (e.args.dest.V3.interior === "Here") ? "Relay" : "Para";
} else { dest = "unknown"; }
} else if (e.args.dest.V4) {
if (e.args.dest.V4.parents === "1") {
dest = (e.args.dest.V4.interior === "Here") ? "Relay" : "Para";
} else { dest = "unknown"; }
} else {
dest = "unknown";
}
return {
blockNumber: e.blockNumber.toString(),
timestamp: e.timestamp.toString(),
counterParty: dest,
amount: -amount,
};
});

const txnLog = incomingLog
.concat(incomingDripsLog)
.concat(incomingXcmLog)
.concat(outgoingLog)
.concat(outgoingXcmLog);
txnLog.sort((a, b) => parseInt(a.timestamp) - parseInt(b.timestamp));
return txnLog;
}

function groupTransactionsByDay(txnLog) {
return txnLog.reduce((acc, cur) => {
const d = new Date(parseInt(cur.timestamp));
Expand Down Expand Up @@ -471,13 +550,15 @@ export async function getMoneyVelocity(
cid
);
} else {
accountingData = await getAccountingData(
api,
account,
cid,
year,
i
);
console.error("not implemented yet for current month");
accountingData = []
// accountingData = await getAccountingData(
// api,
// account,
// cid,
// year,
// i
// );
}

totalTurnoverOrVolume = accountingData.reduce(
Expand Down Expand Up @@ -505,7 +586,7 @@ export async function getMoneyVelocity(

const moneyVelocity = (totalTurnoverOrVolume * 12) / averagetotalIssuance;
if (canBeCached(month, year)) {
db.insertIntoGeneralCache(
await db.insertIntoGeneralCache(
"moneyVelocity",
{ cid, year, month },
{ moneyVelocity }
Expand All @@ -527,7 +608,7 @@ export async function getVolume(cid, year, month) {
const transactionVolume = await getTransactionVolume(cid, start, end);

if (canBeCached(month, year)) {
db.insertIntoGeneralCache(
await db.insertIntoGeneralCache(
"transactionVolume",
{ cid, year, month },
{ transactionVolume }
Expand Down Expand Up @@ -697,7 +778,7 @@ export async function getTransactionActivityLog(
);
data.push(transactionActivityData);

db.insertIntoGeneralCache(
await db.insertIntoGeneralCache(
"transactionActivity",
{ cid, year, month: i },
transactionActivityData
Expand Down
45 changes: 30 additions & 15 deletions db.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,18 @@ class Database {
}

async insertIntoGeneralCache(cacheIdentifier, query, data) {
await this.generalCache.replaceOne(
{ ...query, cacheIdentifier },
{ ...query, cacheIdentifier, data },
{
upsert: true,
}
);
try {
console.debug('inserting into general cache', cacheIdentifier, query)
await this.generalCache.replaceOne(
{ ...query, cacheIdentifier },
{ ...query, cacheIdentifier, data },
{
upsert: true,
}
);
} catch (e) {
console.error(e);
}
}
async getFromGeneralCache(cacheIdentifier, query) {
return (
Expand All @@ -43,13 +48,18 @@ class Database {
}

async insertIntoAccountDataCache(account, year, month, cid, data) {
await this.accountData.replaceOne(
{ account, year, month, cid },
{ account, year, month, cid, data },
{
upsert: true,
}
);
try {
console.debug('inserting into account data cache', account, year, month, cid)
await this.accountData.replaceOne(
{account, year, month, cid},
{account, year, month, cid, data},
{
upsert: true,
}
);
} catch (e) {
console.error(e);
}
}
async getFromAccountDataCache(account, year, cid) {
return (
Expand All @@ -66,13 +76,18 @@ class Database {
}

async insertIntoRewardsDataCache(cid, data) {
await this.rewardsData.replaceOne(
try {
console.debug('inserting into rewards data cache', cid)
await this.rewardsData.replaceOne(
{ cid },
{ cid, data },
{
upsert: true,
}
);
} catch (e) {
console.error(e);
}
}

async getFromRewardsDataCache(cid) {
Expand Down
Loading

0 comments on commit 084809d

Please sign in to comment.