Skip to content

Commit

Permalink
trustwallet#255 - implement ERC721Parser.start() and it's test
Browse files Browse the repository at this point in the history
  • Loading branch information
johnnynanjiang committed Jun 10, 2018
1 parent e690840 commit 4121aa4
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 6 deletions.
7 changes: 6 additions & 1 deletion src/common/BlockchainState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ export class BlockchainState {
lastBackwardBlock: blockInChain,
lastPusherBlock: blockInChain,
lastTokensBlock: blockInChain,
lastTokensBackwardBlock: blockInChain
lastTokensBackwardBlock: blockInChain,
lastTokensBlockForERC721: -1,
}).save()
}

Expand All @@ -37,6 +38,10 @@ export class BlockchainState {
blockInDb.lastTokensBackwardBlock = blockInChain
}

if (!blockInDb.lastTokensBlockForERC721) {
blockInDb.lastTokensBlockForERC721 = -1
}

return blockInDb.save()
})
}
Expand Down
3 changes: 3 additions & 0 deletions src/common/ParseStarter.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { BlockchainParser } from "./BlockchainParser";
import { TokensParser } from "./TokensParser";
import { ERC721Parser } from "./erc721/Erc721Parser";
import { BlockchainState } from "./BlockchainState";
import { PusherScanner } from "../pusher/PusherScanner";
import { setDelay } from "./Utils";

const parser = new BlockchainParser();
const erc721Parser = new ERC721Parser();
const pusher = new PusherScanner();
const tokensParser = new TokensParser();
const blockchainState = new BlockchainState();
Expand All @@ -24,5 +26,6 @@ export class ParseStarter {
parser.start();
pusher.start();
tokensParser.start();
erc721Parser.start();
}
}
52 changes: 48 additions & 4 deletions src/common/erc721/ERC721Parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,24 @@ import { Config } from "../Config";
import { nameABI, ownerOfABI, standardERC721ABI } from "../abi/ABI";
import { contracts } from "../tokens/contracts";
import {
IBlock,
IContract, IDecodedLog, IExtractedTransaction, ISavedTransaction, ITransaction, ITransactionOperation
IBlock, IContract, IDecodedLog, IExtractedTransaction,
ISavedTransaction, ITransaction, ITransactionOperation
} from "../CommonInterfaces";
import { ERC721Contract } from "../../models/Erc721ContractModel";
import { ERC721TransactionOperation } from "../../models/Erc721TransactionOperationModel";
import { ERC721Transaction } from "../../models/Erc721TransactionModel";
import { ERC721Token } from "../../models/Erc721TokenModel";
import { BlockchainState } from "../BlockchainState";
import { LastParsedBlock } from "../../models/LastParsedBlockModel";
import { BlockParser } from "./BlockParser";

export class ERC721Parser {
private abiDecoder = require("abi-decoder");
private abiList = loadContractABIs();

private operationTypes = ["Transfer", "Approval", "approve"];

// TODO: implement cache
private cachedContracts = {};

constructor() {
Expand All @@ -28,12 +32,46 @@ export class ERC721Parser {
}
}

public start() {
winston.info(`ERC721Parser.start()`);

BlockchainState.getBlockState()
.then(([blockInChain, blockInDb]) => {
const lastTokensBlockForERC721: number = blockInDb.lastTokensBlockForERC721
if (lastTokensBlockForERC721 <= blockInChain) {
const blockNumberToParse = lastTokensBlockForERC721 + 1;
new BlockParser().getBlockByNumber(blockNumberToParse)
.then((block) => {
return this.parse(block);
})
.then(() => {
this.saveLastParsedBlock(blockNumberToParse);
Promise.resolve();
})
.catch((err: Error) => {
winston.error(`ERC721Parser.start() at block: ${blockNumberToParse}, error: ${err}`);
});;
}
});
}

public async parse(block): Promise<any[]> {
winston.info(`ERC721Parser.parse(${block.number})`);

const transactions = this.extractTransactions(block);
const transactionIDs = this.getTransactionIDs(transactions);
const receipts = await this.fetchReceiptsFromTransactionIDs(transactionIDs);
const mergedTransactions = this.mergeTransactionsAndReceipts(transactions, receipts);
return Promise.resolve(mergedTransactions);
const mergedTransactions = await this.mergeTransactionsAndReceipts(transactions, receipts);
const results = await this.updateTransactionsInDatabase(mergedTransactions);

const contractAddresses = await this.extractContractAddresses(transactions);
const contracts = await this.getERC721Contracts(contractAddresses);
const savedContracts = await this.updateERC721ContractsInDatabase(contracts);

const transactionOperations = await this.parseTransactionOperations(transactions, savedContracts);
const savedTransactions = await this.updateTransactionOperationsInDatabase(transactionOperations);

return Promise.resolve(savedTransactions);
}

public extractTransactions(block): any[] {
Expand Down Expand Up @@ -332,6 +370,12 @@ export class ERC721Parser {

// ###### private methods ######

private saveLastParsedBlock(blockNumber: number) {
return LastParsedBlock.findOneAndUpdate({}, {lastTokensBlockForERC721: blockNumber}, {upsert: true, new: true}).catch((err: Error) => {
winston.error(`Could not save last parsed block to DB with error: ${err}`);
});
}

private getRawTransactions(block): any[] {
return block.transactions;
}
Expand Down
5 changes: 4 additions & 1 deletion src/models/LastParsedBlockModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ const lastParsedBlockSchema = new Schema({
},
lastTokensBackwardBlock: {
type: Number
}
},
lastTokensBlockForERC721: {
type: Number
},
}, {
versionKey: false,
});
Expand Down
6 changes: 6 additions & 0 deletions test/Common/ERC721/ERC721Parser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,4 +227,10 @@ describe("Test ERC721Parser", () => {

expect(owner1[0].tokens[0]).to.deep.equal(owner2[0].tokens[0]);
})

it("Should start parsing", async () => {
return await erc721Parser.parse(
await new BlockParser().getBlockByNumber(5665445)
);
})
})

0 comments on commit 4121aa4

Please sign in to comment.