Documentation for Gas Relayer pt1
This commit is contained in:
parent
4dd1004c4e
commit
00a203896f
|
@ -1,5 +1,14 @@
|
||||||
|
/**
|
||||||
|
* Message Processor to analyze and execute strategies based on input objects
|
||||||
|
*/
|
||||||
class MessageProcessor {
|
class MessageProcessor {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {object} config Configuration object obtained from `./config/config.js`
|
||||||
|
* @param {object} settings Settings obtained from parsing the configuration object
|
||||||
|
* @param {object} web3 Web3 object already configured
|
||||||
|
* @param {object} events Event emitter
|
||||||
|
*/
|
||||||
constructor(config, settings, web3, events){
|
constructor(config, settings, web3, events){
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
|
@ -7,6 +16,12 @@ class MessageProcessor {
|
||||||
this.events = events;
|
this.events = events;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate input message content
|
||||||
|
* @param {object} contract Contract object obtained from the settings based on the message topic
|
||||||
|
* @param {object} input Input object obtained from a message.
|
||||||
|
* @returns {object} State of validation
|
||||||
|
*/
|
||||||
async _validateInput(contract, input){
|
async _validateInput(contract, input){
|
||||||
console.info("Processing '%s' request to contract: %s", input.action, input.contract);
|
console.info("Processing '%s' request to contract: %s", input.action, input.contract);
|
||||||
|
|
||||||
|
@ -37,6 +52,14 @@ class MessageProcessor {
|
||||||
return {success: true};
|
return {success: true};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process strategy and return validation result
|
||||||
|
* @param {object} contract Contract object obtained from the settings based on the message topic
|
||||||
|
* @param {object} input Input object obtained from a message.
|
||||||
|
* @param {function} reply Reply function to return message
|
||||||
|
* @param {object} strategy Strategy to apply. If undefined, it will use a strategy based on the contract
|
||||||
|
* @returns {object} State of validation
|
||||||
|
*/
|
||||||
async processStrategy(contract, input, reply, strategy){
|
async processStrategy(contract, input, reply, strategy){
|
||||||
const inputValidation = await this._validateInput(contract, input);
|
const inputValidation = await this._validateInput(contract, input);
|
||||||
if(!inputValidation.success){
|
if(!inputValidation.success){
|
||||||
|
@ -62,6 +85,13 @@ class MessageProcessor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process strategy and based on its result, send a transaction to the blockchain
|
||||||
|
* @param {object} contract Contract object obtained from the settings based on the message topic
|
||||||
|
* @param {object} input Input object obtained from a message.
|
||||||
|
* @param {function} reply Reply function to return message
|
||||||
|
* @returns {undefined}
|
||||||
|
*/
|
||||||
async processTransaction(contract, input, reply){
|
async processTransaction(contract, input, reply){
|
||||||
const validationResult = await this.processStrategy(contract, input, reply);
|
const validationResult = await this.processStrategy(contract, input, reply);
|
||||||
|
|
||||||
|
@ -89,7 +119,7 @@ class MessageProcessor {
|
||||||
try {
|
try {
|
||||||
const receipt = await this.web3.eth.sendTransaction(p);
|
const receipt = await this.web3.eth.sendTransaction(p);
|
||||||
// TODO: parse events
|
// TODO: parse events
|
||||||
return reply("Transaction mined", receipt);
|
reply("Transaction mined", receipt);
|
||||||
} catch(err){
|
} catch(err){
|
||||||
reply("Couldn't mine transaction: " + err.message);
|
reply("Couldn't mine transaction: " + err.message);
|
||||||
// TODO log this?
|
// TODO log this?
|
||||||
|
|
|
@ -1,13 +1,22 @@
|
||||||
const Strategy = require('./BaseStrategy');
|
const Strategy = require('./BaseStrategy');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class representing a strategy to validate an 'availability' request.
|
||||||
|
* @extends Strategy
|
||||||
|
*/
|
||||||
class AvailabilityStrategy extends Strategy {
|
class AvailabilityStrategy extends Strategy {
|
||||||
|
|
||||||
async execute(input){
|
/**
|
||||||
|
* Process availability strategy
|
||||||
|
* @param {object} input Input object obtained from an 'availability' request. It expects an object with this structure `{contract, address, action, gasToken, gasPrice}`
|
||||||
|
* @returns {object} Status of validation, and minimum price
|
||||||
|
*/
|
||||||
|
execute(input){
|
||||||
// Verifying if token is allowed
|
// Verifying if token is allowed
|
||||||
const token = this.settings.getToken(input.gasToken);
|
const token = this.settings.getToken(input.gasToken);
|
||||||
if(token == undefined) return {success: false, message: "Token not allowed"};
|
if(token == undefined) return {success: false, message: "Token not allowed"};
|
||||||
|
|
||||||
// TODO Validate gasPrice, and return the minPrice accepted
|
// TODO: Validate gasPrice, and return the minPrice accepted
|
||||||
const minPrice = 0.00;
|
const minPrice = 0.00;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -2,7 +2,17 @@ const ganache = require("ganache-cli");
|
||||||
const Web3 = require('web3');
|
const Web3 = require('web3');
|
||||||
const erc20ABI = require('../../abi/ERC20Token.json');
|
const erc20ABI = require('../../abi/ERC20Token.json');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract class used for validation strategies
|
||||||
|
*/
|
||||||
class BaseStrategy {
|
class BaseStrategy {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {object} web3 Web3 object already configured
|
||||||
|
* @param {object} config Configuration object obtained from `./config/config.js`
|
||||||
|
* @param {object} settings Settings obtained from parsing the configuration object
|
||||||
|
* @param {object} contract Contract object obtained from the settings based on the message topic
|
||||||
|
*/
|
||||||
constructor(web3, config, settings, contract){
|
constructor(web3, config, settings, contract){
|
||||||
this.web3 = web3;
|
this.web3 = web3;
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
|
@ -10,6 +20,12 @@ class BaseStrategy {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain the balance in tokens or ETH from an address
|
||||||
|
* @param {string} address ETH address to obtain the balance from
|
||||||
|
* @param {object} token Token obtained from `settings.getToken(tokenSymbol)`
|
||||||
|
* @returns {web3.utils.BN} Balance
|
||||||
|
*/
|
||||||
async getBalance(address, token){
|
async getBalance(address, token){
|
||||||
// Determining balances of token used
|
// Determining balances of token used
|
||||||
if(token.symbol == "ETH"){
|
if(token.symbol == "ETH"){
|
||||||
|
@ -21,6 +37,11 @@ class BaseStrategy {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build Parameters Function
|
||||||
|
* @param {object} input Input object obtained from an `transaction` request.
|
||||||
|
* @returns {function} Function that simplifies accessing contract functions' parameters
|
||||||
|
*/
|
||||||
_obtainParametersFunc(input){
|
_obtainParametersFunc(input){
|
||||||
const parameterList = this.web3.eth.abi.decodeParameters(this.contract.allowedFunctions[input.functionName].inputs, input.functionParameters);
|
const parameterList = this.web3.eth.abi.decodeParameters(this.contract.allowedFunctions[input.functionName].inputs, input.functionParameters);
|
||||||
return function(parameterName){
|
return function(parameterName){
|
||||||
|
@ -28,6 +49,11 @@ class BaseStrategy {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Estimate gas using web3
|
||||||
|
* @param {object} input Input object obtained from an `transaction` request.
|
||||||
|
* @returns {web3.utils.toBN} Estimated gas fees
|
||||||
|
*/
|
||||||
async _estimateGas(input){
|
async _estimateGas(input){
|
||||||
let p = {
|
let p = {
|
||||||
from: this.config.node.blockchain.account,
|
from: this.config.node.blockchain.account,
|
||||||
|
@ -40,6 +66,8 @@ class BaseStrategy {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simulate transaction using ganache. Useful for obtaining events
|
* Simulate transaction using ganache. Useful for obtaining events
|
||||||
|
* @param {object} input Input object obtained from an `transaction` request.
|
||||||
|
* @returns {object} Simulated transaction receipt
|
||||||
*/
|
*/
|
||||||
async _simulateTransaction(input){
|
async _simulateTransaction(input){
|
||||||
let web3Sim = new Web3(ganache.provider({
|
let web3Sim = new Web3(ganache.provider({
|
||||||
|
|
|
@ -1,8 +1,17 @@
|
||||||
const Strategy = require('./BaseStrategy');
|
const Strategy = require('./BaseStrategy');
|
||||||
const erc20ABI = require('../../abi/ERC20Token.json');
|
const erc20ABI = require('../../abi/ERC20Token.json');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class representing a strategy to validate a `transaction` request when the topic is related to Identities.
|
||||||
|
* @extends Strategy
|
||||||
|
*/
|
||||||
class IdentityStrategy extends Strategy {
|
class IdentityStrategy extends Strategy {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates if the contract being invoked represents an Identity instance
|
||||||
|
* @param {object} input Input object obtained from a `transaction` request.
|
||||||
|
* @returns {bool} Valid instance or not
|
||||||
|
*/
|
||||||
async _validateInstance(input){
|
async _validateInstance(input){
|
||||||
const instanceCodeHash = this.web3.utils.soliditySha3(await this.web3.eth.getCode(input.contract));
|
const instanceCodeHash = this.web3.utils.soliditySha3(await this.web3.eth.getCode(input.contract));
|
||||||
const kernelVerifSignature = this.web3.utils.soliditySha3(this.contract.kernelVerification).slice(0, 10);
|
const kernelVerifSignature = this.web3.utils.soliditySha3(this.contract.kernelVerification).slice(0, 10);
|
||||||
|
@ -15,6 +24,11 @@ class IdentityStrategy extends Strategy {
|
||||||
return this.web3.eth.abi.decodeParameter('bool', verificationResult);
|
return this.web3.eth.abi.decodeParameter('bool', verificationResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process Identity strategy
|
||||||
|
* @param {object} input Input object obtained from an 'transaction' request. It expects an object with this structure `{contract, address, action, functionName, functionParameters, payload}`
|
||||||
|
* @returns {object} Status of validation and estimated gas
|
||||||
|
*/
|
||||||
async execute(input){
|
async execute(input){
|
||||||
if(this.contract.isIdentity){
|
if(this.contract.isIdentity){
|
||||||
let validInstance = await this._validateInstance(input);
|
let validInstance = await this._validateInstance(input);
|
||||||
|
|
|
@ -3,9 +3,17 @@ const Strategy = require('./BaseStrategy');
|
||||||
const TransferSNT = "0x916b6511";
|
const TransferSNT = "0x916b6511";
|
||||||
const ExecuteGasRelayed = "0x754e6ab0";
|
const ExecuteGasRelayed = "0x754e6ab0";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class representing a strategy to validate a `transaction` request when the topic is related to SNTController.
|
||||||
|
* @extends Strategy
|
||||||
|
*/
|
||||||
class SNTStrategy extends Strategy {
|
class SNTStrategy extends Strategy {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process SNTController strategy
|
||||||
|
* @param {object} input Input object obtained from an 'transaction' request. It expects an object with this structure `{contract, address, action, functionName, functionParameters, payload}`
|
||||||
|
* @returns {object} Status of validation and estimated gas
|
||||||
|
*/
|
||||||
async execute(input){
|
async execute(input){
|
||||||
const params = this._obtainParametersFunc(input);
|
const params = this._obtainParametersFunc(input);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue