<commit_before>const async = require('async');
import {__} from 'embark-i18n';
const Web3 = require('web3');

const {blockchain: blockchainConstants} = require('embark-core/constants');
import {dappPath, getAddressToContract, getTransactionParams, hexToNumber} from 'embark-utils';


const Transaction = require('ethereumjs-tx');
const ethUtil = require('ethereumjs-util');

const LISTENED_METHODS = [
  blockchainConstants.transactionMethods.eth_call,
  blockchainConstants.transactionMethods.eth_getTransactionReceipt,
  blockchainConstants.transactionMethods.eth_sendTransaction,
  blockchainConstants.transactionMethods.eth_sendRawTransaction
];

class TransactionLogger {
  constructor(embark, _options) {
    this.embark = embark;
    this.logger = embark.logger;
    this.events = embark.events;
    this.fs = embark.fs;
    this.addressToContract = [];
    this.contractsConfig = embark.config.contractsConfig;
    this.contractsDeployed = false;
    this.outputDone = false;
    this.logFile = dappPath(".embark", "contractLogs.json");
    this.transactions = {};

    this._listenForLogRequests();
    this._registerAPI();

    this.events.on("contracts:log", this._saveLog.bind(this));
    this.events.on('outputDone', () => {
      this.outputDone = true;
    });
    this.events.on("contractsDeployed", () => {
      this.contractsDeployed = true;

      this._getContractsList((contractsList) => {
        this.addressToContract = getAddressToContract(contractsList, this.addressToContract);
      });
    });

    this.writeLogFile = async.cargo((tasks, callback) => {
      const data = this._readLogs();

      tasks.forEach(task => {
        data[new Date().getTime()] = task;
      });

      this.fs.writeJson(this.logFile, data, err => {
        if (err) {
          console.error(err);
        }
        callback();
      });
    });
  }

  get web3() {
    return (async () => {
      if (!this._web3) {
        const provider = await this.events.request2("blockchain:client:provider", "ethereum");
        this._web3 = new Web3(provider);
      }
      return this._web3;
    })();
  }

  _getContractsList(callback) {
    this.events.request("contracts:list", (err, contractsList) => {
      if (err) {
        this.logger.error(__("no contracts found"));
        return callback();
      }
      callback(contractsList);
    });
  }

  _listenForLogRequests() {
    this.events.on('deploy:contract:receipt', receipt => {
      this.events.emit('contracts:log', {
        name: receipt.className,
        functionName: 'constructor',
        paramString: '',
        address: receipt.contractAddress,
        status: receipt.status ? '0x1' : '0x0',
        gasUsed: receipt.gasUsed,
        blockNumber: receipt.blockNumber,
        transactionHash: receipt.transactionHash
      });
    });

    this.events.on('blockchain:proxy:response', this._onLogRequest.bind(this));
  }

  async _onLogRequest(args) {
    const method = args.reqData.method;
    if (!this.contractsDeployed || !LISTENED_METHODS.includes(method)) {
      return;
    }

    if (method === blockchainConstants.transactionMethods.eth_sendTransaction) {
      // We just gather data and wait for the receipt
      this.transactions[args.respData.result] = {
        address: args.reqData.params[0].to,
        data: args.reqData.params[0].data,
        txHash: args.respData.result
      };
      return;
    } else if (method === blockchainConstants.transactionMethods.eth_sendRawTransaction) {
      const rawData = Buffer.from(ethUtil.stripHexPrefix(args.reqData.params[0]), 'hex');
      const tx = new Transaction(rawData, 'hex');
      this.transactions[args.respData.result] = {
        address: '0x' + tx.to.toString('hex'),
        data: '0x' + tx.data.toString('hex')
      };
      return;
    }

    let dataObject;
    if (method === blockchainConstants.transactionMethods.eth_getTransactionReceipt) {
      dataObject = args.respData.result;
      if (!dataObject) {
        return;
      }
      if (this.transactions[args.respData.result.transactionHash]) {
        // This is the normal case. If we don't get here, it's because we missed a TX
        dataObject = Object.assign(dataObject, this.transactions[args.respData.result.transactionHash]);
        delete this.transactions[args.respData.result.transactionHash]; // No longer needed
      }
    } else {
      dataObject = args.reqData.params[0];
    }
    const {to: address, data} = dataObject;
    if (!address) {
      // It's a deployment
      return;
    }
    const contract = this.addressToContract[address];

    if (!contract) {
      this.logger.info(`Contract log for unknown contract: ${JSON.stringify(args)}`);
      return this._getContractsList((contractsList) => {
        this.addressToContract = getAddressToContract(contractsList, this.addressToContract);
      });
    }

    const {name, silent} = contract;
    if (silent && !this.outputDone) {
      return;
    }

    let functionName, paramString;
    if (!data) {
      // We missed the TX
      functionName = 'unknown';
      paramString = 'unknown';<commit_msg>fix(@embark/transaction-logger): don't show logs for stray receipts<commit_after>const async = require('async');
import {__} from 'embark-i18n';
const Web3 = require('web3');

const {blockchain: blockchainConstants} = require('embark-core/constants');
import {dappPath, getAddressToContract, getTransactionParams, hexToNumber} from 'embark-utils';


const Transaction = require('ethereumjs-tx');
const ethUtil = require('ethereumjs-util');

const LISTENED_METHODS = [
  blockchainConstants.transactionMethods.eth_call,
  blockchainConstants.transactionMethods.eth_getTransactionReceipt,
  blockchainConstants.transactionMethods.eth_sendTransaction,
  blockchainConstants.transactionMethods.eth_sendRawTransaction
];

class TransactionLogger {
  constructor(embark, _options) {
    this.embark = embark;
    this.logger = embark.logger;
    this.events = embark.events;
    this.fs = embark.fs;
    this.addressToContract = [];
    this.contractsConfig = embark.config.contractsConfig;
    this.contractsDeployed = false;
    this.outputDone = false;
    this.logFile = dappPath(".embark", "contractLogs.json");
    this.transactions = {};

    this._listenForLogRequests();
    this._registerAPI();

    this.events.on("contracts:log", this._saveLog.bind(this));
    this.events.on('outputDone', () => {
      this.outputDone = true;
    });
    this.events.on("contractsDeployed", () => {
      this.contractsDeployed = true;

      this._getContractsList((contractsList) => {
        this.addressToContract = getAddressToContract(contractsList, this.addressToContract);
      });
    });

    this.writeLogFile = async.cargo((tasks, callback) => {
      const data = this._readLogs();

      tasks.forEach(task => {
        data[new Date().getTime()] = task;
      });

      this.fs.writeJson(this.logFile, data, err => {
        if (err) {
          console.error(err);
        }
        callback();
      });
    });
  }

  get web3() {
    return (async () => {
      if (!this._web3) {
        const provider = await this.events.request2("blockchain:client:provider", "ethereum");
        this._web3 = new Web3(provider);
      }
      return this._web3;
    })();
  }

  _getContractsList(callback) {
    this.events.request("contracts:list", (err, contractsList) => {
      if (err) {
        this.logger.error(__("no contracts found"));
        return callback();
      }
      callback(contractsList);
    });
  }

  _listenForLogRequests() {
    this.events.on('deploy:contract:receipt', receipt => {
      this.events.emit('contracts:log', {
        name: receipt.className,
        functionName: 'constructor',
        paramString: '',
        address: receipt.contractAddress,
        status: receipt.status ? '0x1' : '0x0',
        gasUsed: receipt.gasUsed,
        blockNumber: receipt.blockNumber,
        transactionHash: receipt.transactionHash
      });
    });

    this.events.on('blockchain:proxy:response', this._onLogRequest.bind(this));
  }

  async _onLogRequest(args) {
    const method = args.reqData.method;
    if (!this.contractsDeployed || !LISTENED_METHODS.includes(method)) {
      return;
    }

    if (method === blockchainConstants.transactionMethods.eth_sendTransaction) {
      // We just gather data and wait for the receipt
      this.transactions[args.respData.result] = {
        address: args.reqData.params[0].to,
        data: args.reqData.params[0].data,
        txHash: args.respData.result
      };
      return;
    } else if (method === blockchainConstants.transactionMethods.eth_sendRawTransaction) {
      const rawData = Buffer.from(ethUtil.stripHexPrefix(args.reqData.params[0]), 'hex');
      const tx = new Transaction(rawData, 'hex');
      this.transactions[args.respData.result] = {
        address: '0x' + tx.to.toString('hex'),
        data: '0x' + tx.data.toString('hex')
      };
      return;
    }

    let dataObject;
    if (method === blockchainConstants.transactionMethods.eth_getTransactionReceipt) {
      dataObject = args.respData.result;
      if (!dataObject) {
        return;
      }
      if (this.transactions[args.respData.result.transactionHash]) {
        // This is the normal case. If we don't get here, it's because we missed a TX
        dataObject = Object.assign(dataObject, this.transactions[args.respData.result.transactionHash]);
        delete this.transactions[args.respData.result.transactionHash]; // No longer needed
      } else {
        // Was not a eth_getTransactionReceipt in the context of a transaction
        return;
      }
    } else {
      dataObject = args.reqData.params[0];
    }
    const {to: address, data} = dataObject;
    if (!address) {
      // It's a deployment
      return;
    }
    const contract = this.addressToContract[address];

    if (!contract) {
      this.logger.info(`Contract log for unknown contract: ${JSON.stringify(args)}`);
      return this._getContractsList((contractsList) => {
        this.addressToContract = getAddressToContract(contractsList, this.addressToContract);
      });
    }

    const {name, silent} = contract;
    if (silent && !this.outputDone) {
      return;
    }

    let functionName, paramString;
    if (!data) {
      // We missed the TX
      functionName = 'unknown';
      paramString = 'unknown';
{'fraction_non_alphanumeric': 0.1319337442218798, 'fraction_numerical': 0.003852080123266564, 'mean_word_length': 3.0251937984496124, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '668483', 'n_tokens_mistral': 3130, 'n_tokens_neox': 3058, 'n_words': 565}