-
Notifications
You must be signed in to change notification settings - Fork 14
Expand file tree
/
Copy pathdb_analysis.js
More file actions
124 lines (106 loc) · 3.59 KB
/
db_analysis.js
File metadata and controls
124 lines (106 loc) · 3.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import AWS from "aws-sdk";
AWS.config.update({ region: "us-east-2" });
export async function scanTable(){
var ddb = new AWS.DynamoDB({ });
const params = {
// Specify which items in the results are returned.
FilterExpression: "nonce > :s",
// Define the expression attribute value, which are substitutes for the values you want to compare.
ExpressionAttributeValues: {
":s": {N: "0"}
},
// Set the projection expression, which the the attributes that you want.
ProjectionExpression: "txto, txfrom, txinput, gas, gasPrice, nonce, txtype, txvalue, attacking",
TableName: "test_table",
};
// ddb.scan(params, function(err, data) {
// if (err) {
// console.log("Error", err);
// } else {
// data.Items.forEach(function (element, index, array){
// console.log(element);
// console.log(array);
// });
// }
// });
return await new Promise((resolve, reject) => {
ddb.scan(params, (err, data) => {
if (err) reject(err);
resolve(data);
})
});
}
function dbAnalytics(data){
var attackingTxns = [];
var nonAttackingTxns = [];
var stats = {}
data.Items.forEach((element, _, __) => {
if(element['attacking']['BOOL']){
attackingTxns.push(element);
}else{
nonAttackingTxns.push(element);
}
});
stats['attackingCount'] = attackingTxns.length;
stats['nonAttackingCount'] = nonAttackingTxns.length;
var avgAttackGas = 0;
attackingTxns.forEach((element, _, __) => {
avgAttackGas += parseInt(element.gas.N);
});
if(attackingTxns.length){
avgAttackGas/=attackingTxns.length;
}
stats['avgAttackGas'] = avgAttackGas;
var avgNonAttackGas = 0;
var avgNonAttackGasPrice = 0;
var avgTxValue = 0;
nonAttackingTxns.forEach((element, _, __) => {
avgNonAttackGas += parseInt(element.gas.N);
avgNonAttackGasPrice += parseInt(element.gasPrice.N);
avgTxValue += parseInt(element.txvalue.N);
});
if(nonAttackingTxns){
avgNonAttackGasPrice/=nonAttackingTxns.length;
avgNonAttackGas/=nonAttackingTxns.length;
avgTxValue/=nonAttackingTxns.length;
}
stats['avgNonAttackGas'] = avgNonAttackGas;
stats['avgNonAttackGasPrice'] = avgNonAttackGasPrice;
stats['avgTxValue'] = avgTxValue;
let uniqueAddresses = new Map();
let topRelayers = new Map();
nonAttackingTxns.forEach((element, _, __) => {
if (uniqueAddresses.has(element.txfrom.S)){
uniqueAddresses.set(element.txfrom.S, uniqueAddresses.get(element.txfrom.S)+1);
}else{
uniqueAddresses.set(element.txfrom.S, 1);
}
if (topRelayers.has(element.txto.S)){
topRelayers.set(element.txto.S, topRelayers.get(element.txto.S)+1);
} else {
topRelayers.set(element.txto.S, 1);
}
});
stats['uniqueAddressesAttacked'] = uniqueAddresses.size;
stats['uniqueRelayersUsed'] = topRelayers.size;
// magic js that sorts the map
const mapSort1 = [...uniqueAddresses.entries()].sort((a, b) => b[1] - a[1]);
const mapSort2 = [...topRelayers.entries()].sort((a, b) => b[1] - a[1]);
var topAddresses;
if (mapSort1.length <= 10){
topAddresses = mapSort1;
}else {
topAddresses = mapSort1.slice(0, 10);
}
stats['topAddresses'] = topAddresses;
var top10Relayers;
if (mapSort2.length <= 10){
top10Relayers = mapSort2;
}else {
top10Relayers = mapSort2.slice(0, 10);
}
stats['topRelayers'] = top10Relayers;
console.log(stats);
return stats;
}
scanTable().then(dbAnalytics);