Skip to content

Commit 33b5ab0

Browse files
committed
merge develop
2 parents f524303 + ccd9c21 commit 33b5ab0

13 files changed

+552
-48
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## [3.27.0] - 2024-02-16
8+
### Added
9+
- Start inserting analytics events in tsdb
10+
711
## [3.26.11] - 2024-02-16
812
### Fixed
913
- Gas limit bug

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ethernal",
3-
"version": "3.26.11",
3+
"version": "3.27.0",
44
"private": true,
55
"scripts": {
66
"serve": "vue-cli-service serve",

run/lib/utils.js

+11-1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,15 @@ const _sanitize = (obj, numberization = true) => {
6868
);
6969
};
7070

71+
const stringify = (obj) => {
72+
if (ethers.BigNumber.isBigNumber(obj) || isStringifiedBN(obj))
73+
return ethers.BigNumber.from(obj).toString();
74+
else if (typeof obj.toString == 'function')
75+
return obj.toString();
76+
else
77+
return String(obj);
78+
};
79+
7180
const _stringifyBns = (obj) => {
7281
var res = {}
7382
for (const key in obj) {
@@ -87,5 +96,6 @@ module.exports = {
8796
isJson: _isJson,
8897
getEnv: getEnv,
8998
withTimeout: withTimeout,
90-
slugify
99+
slugify,
100+
stringify
91101
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
'use strict';
2+
3+
/** @type {import('sequelize-cli').Migration} */
4+
module.exports = {
5+
async up (queryInterface, Sequelize) {
6+
const transaction = await queryInterface.sequelize.transaction();
7+
try {
8+
await queryInterface.createTable('transaction_events', {
9+
workspaceId: {
10+
type: Sequelize.INTEGER,
11+
allowNull: false,
12+
references: {
13+
key: 'id',
14+
model: {
15+
tableName: 'workspaces'
16+
}
17+
}
18+
},
19+
transactionId: {
20+
primaryKey: true,
21+
type: Sequelize.INTEGER,
22+
allowNull: false,
23+
references: {
24+
key: 'id',
25+
model: {
26+
tableName: 'transactions'
27+
}
28+
}
29+
},
30+
blockNumber : {
31+
type: Sequelize.INTEGER,
32+
allowNull: false,
33+
},
34+
timestamp: {
35+
primaryKey: true,
36+
type: 'TIMESTAMPTZ',
37+
allowNull: false,
38+
},
39+
transactionFee: {
40+
type: 'NUMERIC',
41+
allowNull: false
42+
},
43+
gasPrice: {
44+
type: 'NUMERIC',
45+
allowNull: false
46+
},
47+
gasUsed: {
48+
type: 'NUMERIC',
49+
allowNull: false
50+
},
51+
from: {
52+
type: 'VARCHAR(42)',
53+
allowNull: false
54+
},
55+
to: {
56+
type: 'VARCHAR(42)',
57+
allowNull: true
58+
}
59+
}, { transaction });
60+
61+
await queryInterface.sequelize.query(`SELECT create_hypertable('transaction_events', 'timestamp');`, { transaction });
62+
await queryInterface.sequelize.query(`
63+
CREATE INDEX "transaction_events_workspaceId_timestamp" ON transaction_events("workspaceId", timestamp DESC);
64+
`, { transaction });
65+
66+
await queryInterface.createTable('token_transfer_events', {
67+
workspaceId: {
68+
type: Sequelize.INTEGER,
69+
allowNull: false,
70+
references: {
71+
key: 'id',
72+
model: {
73+
tableName: 'workspaces'
74+
}
75+
}
76+
},
77+
tokenTransferId: {
78+
primaryKey: true,
79+
type: Sequelize.INTEGER,
80+
allowNull: false,
81+
references: {
82+
key: 'id',
83+
model: {
84+
tableName: 'token_transfers'
85+
}
86+
}
87+
},
88+
blockNumber : {
89+
type: Sequelize.INTEGER,
90+
allowNull: false,
91+
},
92+
timestamp: {
93+
primaryKey: true,
94+
type: 'TIMESTAMPTZ',
95+
allowNull: false,
96+
},
97+
amount: {
98+
type: 'NUMERIC',
99+
allowNull: false
100+
},
101+
token: {
102+
type: 'VARCHAR(42)',
103+
allowNull: false
104+
},
105+
tokenType: {
106+
type: Sequelize.STRING,
107+
allowNull: true
108+
},
109+
src: {
110+
type: 'VARCHAR(42)',
111+
allowNull: false
112+
},
113+
dst: {
114+
type: 'VARCHAR(42)',
115+
allowNull: false
116+
}
117+
}, { transaction });
118+
await queryInterface.sequelize.query(`SELECT create_hypertable('token_transfer_events', 'timestamp');`, { transaction });
119+
await queryInterface.sequelize.query(`
120+
CREATE INDEX "token_transfer_events_workspaceId_timestamp" ON transaction_events("workspaceId", timestamp DESC);
121+
`, { transaction });
122+
123+
await queryInterface.createTable('token_balance_change_events', {
124+
workspaceId: {
125+
type: Sequelize.INTEGER,
126+
allowNull: false,
127+
references: {
128+
key: 'id',
129+
model: {
130+
tableName: 'workspaces'
131+
}
132+
}
133+
},
134+
tokenBalanceChangeId: {
135+
primaryKey: true,
136+
type: Sequelize.INTEGER,
137+
allowNull: false,
138+
references: {
139+
key: 'id',
140+
model: {
141+
tableName: 'token_balance_changes'
142+
}
143+
}
144+
},
145+
blockNumber : {
146+
type: Sequelize.INTEGER,
147+
allowNull: false,
148+
},
149+
timestamp: {
150+
primaryKey: true,
151+
type: 'TIMESTAMPTZ',
152+
allowNull: false,
153+
},
154+
token: {
155+
type: 'VARCHAR(42)',
156+
allowNull: false
157+
},
158+
address: {
159+
type: 'VARCHAR(42)',
160+
allowNull: false
161+
},
162+
currentBalance: {
163+
type: 'NUMERIC',
164+
allowNull: false
165+
},
166+
tokenType: {
167+
type: Sequelize.STRING,
168+
allowNull: true
169+
},
170+
}, { transaction });
171+
await queryInterface.sequelize.query(`SELECT create_hypertable('token_balance_change_events', 'timestamp');`, { transaction });
172+
await queryInterface.sequelize.query(`
173+
CREATE INDEX "token_balance_change_events_workspaceId_timestamp" ON token_balance_change_events("workspaceId", timestamp DESC);
174+
`, { transaction });
175+
176+
await transaction.commit();
177+
} catch(error) {
178+
console.log(error);
179+
await transaction.rollback();
180+
throw error;
181+
}
182+
},
183+
184+
async down (queryInterface, Sequelize) {
185+
const transaction = await queryInterface.sequelize.transaction();
186+
try {
187+
await queryInterface.dropTable('transaction_events', { transaction });
188+
await queryInterface.dropTable('token_transfer_events', { transaction });
189+
await queryInterface.dropTable('token_balance_change_events', { transaction });
190+
191+
await transaction.commit();
192+
} catch(error) {
193+
console.log(error);
194+
await transaction.rollback();
195+
throw error;
196+
}
197+
}
198+
};

run/models/tokenbalancechange.js

+40
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const {
44
Sequelize
55
} = require('sequelize');
66
const Op = Sequelize.Op;
7+
const ethers = require('ethers');
78

89
module.exports = (sequelize, DataTypes) => {
910
class TokenBalanceChange extends Model {
@@ -16,6 +17,7 @@ module.exports = (sequelize, DataTypes) => {
1617
TokenBalanceChange.belongsTo(models.Transaction, { foreignKey: 'transactionId', as: 'transaction' });
1718
TokenBalanceChange.belongsTo(models.Workspace, { foreignKey: 'workspaceId', as: 'workspace' });
1819
TokenBalanceChange.belongsTo(models.TokenTransfer, { foreignKey: 'tokenTransferId', as: 'tokenTransfer' });
20+
TokenBalanceChange.hasOne(models.TokenBalanceChangeEvent, { foreignKey: 'tokenBalanceChangeId', as: 'event' });
1921
TokenBalanceChange.hasOne(models.Contract, {
2022
sourceKey: 'token',
2123
foreignKey: 'address',
@@ -29,6 +31,39 @@ module.exports = (sequelize, DataTypes) => {
2931
constraints: false
3032
});
3133
}
34+
35+
getContract() {
36+
return sequelize.models.Contract.findOne({
37+
where: {
38+
workspaceId: this.workspaceId,
39+
address: this.token
40+
}
41+
});
42+
}
43+
44+
async safeDestroy(transaction) {
45+
const event = await this.getEvent();
46+
if (event)
47+
await event.destroy({ transaction });
48+
49+
return this.destroy({ transaction });
50+
}
51+
52+
async insertAnalyticEvent(sequelizeTransaction) {
53+
const transaction = await this.getTransaction();
54+
const contract = await this.getContract();
55+
56+
return sequelize.models.TokenBalanceChange.create({
57+
workspaceId: this.workspaceId,
58+
tokenBalanceChangeId: this.id,
59+
blockNumber: transaction.blockNumber,
60+
timestamp: transaction.timestamp,
61+
token: this.token,
62+
address: this.address,
63+
currentBalance: ethers.BigNumber.from(this.currentBalance).toString(),
64+
tokenType: contract ? contract.patterns[0] : null
65+
}, { transaction: sequelizeTransaction });
66+
}
3267
}
3368
TokenBalanceChange.init({
3469
transactionId: DataTypes.INTEGER,
@@ -50,6 +85,11 @@ module.exports = (sequelize, DataTypes) => {
5085
previousBalance: DataTypes.STRING,
5186
diff: DataTypes.STRING
5287
}, {
88+
hooks: {
89+
async afterCreate(tokenBalanceChange, options) {
90+
await tokenBalanceChange.insertAnalyticEvent(options.transaction);
91+
}
92+
},
5393
sequelize,
5494
modelName: 'TokenBalanceChange',
5595
tableName: 'token_balance_changes'

run/models/tokenbalancechangeevent.js

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
'use strict';
2+
const {
3+
Model
4+
} = require('sequelize');
5+
module.exports = (sequelize, DataTypes) => {
6+
class TokenBalanceChangeEvent extends Model {
7+
/**
8+
* Helper method for defining associations.
9+
* This method is not a part of Sequelize lifecycle.
10+
* The `models/index` file will call this method automatically.
11+
*/
12+
static associate(models) {
13+
// define association here
14+
}
15+
}
16+
TokenBalanceChangeEvent.init({
17+
workspaceId: DataTypes.INTEGER,
18+
tokenBalanceChangeId: DataTypes.INTEGER,
19+
blockNumber: DataTypes.INTEGER,
20+
timestamp: {
21+
primaryKey: true,
22+
type: DataTypes.DATE
23+
},
24+
token: DataTypes.STRING,
25+
address: DataTypes.STRING,
26+
currentBalance: DataTypes.NUMERIC,
27+
tokenType: DataTypes.STRING,
28+
}, {
29+
sequelize,
30+
timestamps: false,
31+
modelName: 'TokenBalanceChangeEvent',
32+
tableName: 'token_balance_change_events'
33+
});
34+
return TokenBalanceChangeEvent;
35+
};

0 commit comments

Comments
 (0)