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

F 51 refactor event processing #54

Merged
merged 5 commits into from
Sep 4, 2021
Merged
Show file tree
Hide file tree
Changes from 3 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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,4 @@ $RECYCLE.BIN/

# Others
data/
config/local.json
71 changes: 63 additions & 8 deletions feathers-src/lib/populate.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ const processNextWaitingEvent = async () => {
const query = {
status: EventStatus.WAITING,
$sort: {
// maybe we get some events from home and blockchain with different blockNumber, so the transactionTime
// should be the first important thing for decide what event should process first
timestamp: 1,
isHomeEvent: 1,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this one can be removed

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isHomeEvent removed

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Event blockNumber I guess is not needed

blockNumber: 1,
transactionIndex: 1,
Expand Down Expand Up @@ -114,6 +117,64 @@ async function fetchForeignEvents(foreignRange) {
return events;
}


/**
* fetches the transaction for the given hash in foreign network.
*
* first checks if the transaction has been saved in db
* if it misses, we fetch the block using web3 and save it in db
*
* if we are currently fetching a given hash, we will not fetch it twice.
* instead, we resolve the promise after we fetch the transaction for the hash.
*
* @param {string} hash the hash to fetch the transaction of
* @param {boolean} isHome get transaction of home network
*/
const getTransaction = async (hash, isHome = false) => {
if (!hash) {
throw new errors.NotFound(`Hash value cannot be undefined`);
}
const Transaction = app.get('transactionsModel');
const query = { hash, isHome };
const result = await Transaction.findOne(query);
if (result) {
return result;
}

const web3 = isHome ? getHomeWeb3() : getForeignWeb3();
const tx = await web3.eth.getTransaction(hash);
if (!tx) {
// sometimes tx is not null but the tx.blockNumber is null (maybe when transaction is not mined already)
throw new errors.NotFound(`Not tx found for ${hash}`);
}
const { from, blockNumber } = tx;

const model = {
hash,
from,
isHome: !!isHome,
};

// Transaction is mined
if (blockNumber) {
model.blockNumber = blockNumber;

const { timestamp } = await web3.eth.getBlock(blockNumber);
model.timestamp = new Date(timestamp * 1000);
const transaction = new Transaction(model);
await transaction.save();
}
return model;
};

const createEvent = async (event, isHomeEvent)=>{
const {timestamp} = await getTransaction(event.transactionHash, isHomeEvent)
await app
.service('events')
.create({ isHomeEvent, timestamp, ...event })
.catch(err => logger.error(JSON.stringify(event, null, 2), err))
}

const populate = async () => {
logger.debug('Fetch initial block numbers');
setLastForeignBlock((await getLastBlock()) + 1);
Expand Down Expand Up @@ -204,10 +265,7 @@ const populate = async () => {
try {
await Promise.all(
homeEvents.map(event =>
app
.service('events')
.create({ isHomeEvent: true, ...event })
.catch(err => logger.error(JSON.stringify(event, null, 2), err)),
createEvent(event, true)
),
);
} catch (err) {
Expand All @@ -216,10 +274,7 @@ const populate = async () => {
try {
await Promise.all(
foreignEvents.map(event =>
app
.service('events')
.create({ isHomeEvent: false, ...event })
.catch(err => logger.error(JSON.stringify(event, null, 2), err)),
createEvent(event, false)
),
);
} catch (err) {
Expand Down
4 changes: 2 additions & 2 deletions feathers-src/lib/web3Provider.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const HomeBridgeContract = require('giveth-bridge/build/GivethBridge.json');
const ForeignBridgeContract = require('giveth-bridge/build/ForeignGivethBridge.json');
const HomeBridgeContract = require('@giveth/bridge-contract/build/GivethBridge.json');
const ForeignBridgeContract = require('@giveth/bridge-contract/build/ForeignGivethBridge.json')
const Web3 = require('web3');
const logger = require('winston');
const EventEmitter = require('events');
Expand Down
1 change: 1 addition & 0 deletions feathers-src/models/events.model.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const createModel = app => {
processingError: { type: String },
confirmations: { type: Number, require: true },
isHomeEvent: { type: Boolean, default: false, index: true },
timestamp: { type: Date },
},
{
timestamp: true,
Expand Down
24 changes: 24 additions & 0 deletions feathers-src/models/transactions.model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
function Transaction(app) {
const mongooseClient = app.get('mongooseClient');
const { Schema } = mongooseClient;
const transaction = new Schema(
{
hash: { type: String, required: true, index: true },
from: { type: String },
gasPrice: { type: Number },
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just fields of hash, blockNumber, isHome and timestamp are needed, plus transactionIndex

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, extra fields removed
@aminlatifi

gasUsed: { type: Number },
blockNumber: { type: Number },
isHome: { type: Boolean, default: false },
timestamp: { type: Date },
},
{
timestamps: false,
},
);

return mongooseClient.model('transactions', transaction);
}

module.exports = {
createModel: Transaction,
};
2 changes: 2 additions & 0 deletions feathers-src/services/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const spenders = require('./spenders/spenders.service');
const depositors = require('./depositors/depositors.service');
const information = require('./information/information.service');
const events = require('./events/events.service');
const transactions = require('./transactions/transactions.service');

// eslint-disable-next-line no-unused-vars
module.exports = app => {
Expand All @@ -17,4 +18,5 @@ module.exports = app => {
app.configure(depositors);
app.configure(information);
app.configure(events);
app.configure(transactions);
};
10 changes: 10 additions & 0 deletions feathers-src/services/transactions/transactions.service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Initializes the `transactions` model and save it in app
const { createModel } = require('../../models/transactions.model');

module.exports = function serviceFactory() {
const app = this;
const Model = createModel(app);

// Save transaction model
app.set('transactionsModel', Model);
};
Loading