Skip to content

Commit

Permalink
Logic for automatic contract instances updates when Hub is updated (#123
Browse files Browse the repository at this point in the history
)

* Added custom BlockchainError and decorator in order to handle updated contracts in the Hub

* Add blockchain constants

* Remove shortening of blockchain name

* Add chainId to blockchain constants

* Add set right blockchain name if old are used

* Add constants intstead of strings

* Added function to validate options for the 'isValidUAL' function

* Added additional info to the errors in the 'isValidUAL' function

* Add case insensitive comparison for contract address

* Add hardhat2 constants

* Fix missing comma

* Add chain it to chiado and gnosis

* Rename chiado to gnosis

* Bumped version to 6.1.0

* Validate blockchain name withou network name

* Added 'environment' to options, splitted blockchains by environment, remove redundant code, added logic to update contracts when executing contract functions

* Fixes for new UALs

* Remove decorator

* Fix add await when calling updateContractInstances

* Fix use correct error reference

* Update dkg-evm-module version

* Add fethingc gas price from gnosis oracle

* Add logic for using gas price oracle to getNetworkGasPrice method

* Add missing await

* Return gas value

* Fix using correct blockchain name

* Fix return gasPrice in getNetworkGasPrice

* Use gasPriceOracleLink from constants

* Fix priceOracleLink

* Fix getting gas for gnosis mainnet

* Add webpack build

* Fixed logic for automatic contract instances updates when Hub is updated

* Fix error using reference from try block in catch

* Remove BlockchainError

* Added force flag for contracts update

* Fix fetching new address and updating contract

* Remove console.log & update version to 6.1.1

---------

Co-authored-by: Mihajlo Pavlovic <mihajlo.pavlovic@origin-trail.com>
Co-authored-by: NZT48 <nikolaztodorovic26@gmail.com>
  • Loading branch information
3 people authored Dec 29, 2023
1 parent 719e9e8 commit 91513a0
Show file tree
Hide file tree
Showing 10 changed files with 85 additions and 32 deletions.
2 changes: 1 addition & 1 deletion constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const BLOCKCHAINS = {
rpc: 'http://localhost:9545',
hubContract: '0x5FbDB2315678afecb367f032d93F642f64180aa3',
},
'otp::2043': {
'otp:2043': {
rpc: 'http://parachain-alphanet-02.origin-trail.network:9933',
hubContract: '0x7585a99C5C150a08f5CDeFD16465C6De8D41EbbD',
},
Expand Down
2 changes: 1 addition & 1 deletion dist/dkg.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion examples/demo-private.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const DkgClient = new DKG({
endpoint: OT_NODE_HOSTNAME,
port: OT_NODE_PORT,
blockchain: {
name: 'ganache',
name: 'hardhat1',
publicKey: PUBLIC_KEY,
privateKey: PRIVATE_KEY,
},
Expand Down
2 changes: 1 addition & 1 deletion examples/demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ <h3>Asset data</h3>
el: '#app',
data: function () {
return {
selectedNetwork: 'hardhat',
selectedNetwork: 'hardhat1',
disabled: false,
getResult: [],
getUAL: '',
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dkg.js",
"version": "6.1.0",
"version": "6.1.1",
"description": "Javascript library for interaction with the OriginTrail Decentralized Knowledge Graph",
"main": "index.js",
"scripts": {
Expand Down
44 changes: 35 additions & 9 deletions services/blockchain-service/blockchain-service-base.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,28 @@ class BlockchainServiceBase {
}

async callContractFunction(contractName, functionName, args, blockchain) {
const contractInstance = await this.getContractInstance(contractName, blockchain);
return contractInstance.methods[functionName](...args).call();
let contractInstance = await this.getContractInstance(contractName, blockchain);
try {
return await contractInstance.methods[functionName](...args).call();
} catch (error) {
if (/revert|VM Exception/i.test(error.message)) {
let status;
try {
status = await contractInstance.methods.status().call();
} catch (_) {
status = false;
}

if (!status) {
await this.updateContractInstance(contractName, blockchain, true);
contractInstance = await this.getContractInstance(contractName, blockchain);

return contractInstance.methods[functionName](...args).call();
}
}

throw error;
}
}

async prepareTransaction(contractInstance, functionName, args, blockchain) {
Expand Down Expand Up @@ -134,7 +154,7 @@ class BlockchainServiceBase {
return this[blockchain.name].web3;
}

async getContractAddress(contractName, blockchain) {
async getContractAddress(contractName, blockchain, force = false) {
this.ensureBlockchainInfo(blockchain);
if (!this[blockchain.name].contracts[blockchain.hubContract]) {
this[blockchain.name].contracts[blockchain.hubContract] = {};
Expand All @@ -145,7 +165,10 @@ class BlockchainServiceBase {
new web3Instance.eth.Contract(this.abis.Hub, blockchain.hubContract);
}

if (!this[blockchain.name].contractAddresses[blockchain.hubContract][contractName]) {
if (
force ||
!this[blockchain.name].contractAddresses[blockchain.hubContract][contractName]
) {
this[blockchain.name].contractAddresses[blockchain.hubContract][contractName] =
await this.callContractFunction(
'Hub',
Expand All @@ -159,16 +182,19 @@ class BlockchainServiceBase {
return this[blockchain.name].contractAddresses[blockchain.hubContract][contractName];
}

async updateContractInstance(contractName, blockchain) {
async updateContractInstance(contractName, blockchain, force = false) {
this.ensureBlockchainInfo(blockchain);
if (!this[blockchain.name].contractAddresses[blockchain.hubContract][contractName]) {
if (
force ||
!this[blockchain.name].contractAddresses[blockchain.hubContract][contractName]
) {
this[blockchain.name].contractAddresses[blockchain.hubContract][contractName] =
await this.getContractAddress(contractName, blockchain);
await this.getContractAddress(contractName, blockchain, force);
}
if (!this[blockchain.name].contracts[blockchain.hubContract][contractName]) {
if (force || !this[blockchain.name].contracts[blockchain.hubContract][contractName]) {
const web3Instance = await this.getWeb3Instance(blockchain);
this[blockchain.name].contracts[blockchain.hubContract][contractName] =
new web3Instance.eth.Contract(
await new web3Instance.eth.Contract(
this.abis[contractName],
this[blockchain.name].contractAddresses[blockchain.hubContract][contractName],
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,30 @@ class BrowserBlockchainService extends BlockchainServiceBase {
}

async executeContractFunction(contractName, functionName, args, blockchain) {
const contractInstance = await this.getContractInstance(contractName, blockchain);
let contractInstance = await this.getContractInstance(contractName, blockchain);
const tx = await this.prepareTransaction(contractInstance, functionName, args, blockchain);

return contractInstance.methods[functionName](...args).send(tx);
try {
return await contractInstance.methods[functionName](...args).send(tx);
} catch (error) {
if (/revert|VM Exception/i.test(error.message)) {
let status;
try {
status = await contractInstance.methods.status().call();
} catch (_) {
status = false;
}

if (!status) {
await this.updateContractInstance(contractName, blockchain, true);
contractInstance = await this.getContractInstance(contractName, blockchain);

return contractInstance.methods[functionName](...args).send(tx);
}
}

throw error;
}
}

async getPublicKey() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,14 @@ class NodeBlockchainService extends BlockchainServiceBase {

async executeContractFunction(contractName, functionName, args, blockchain) {
const web3Instance = await this.getWeb3Instance(blockchain);
let contractInstance = await this.getContractInstance(contractName, blockchain);

let result;
let previousTxGasPrice;
let transactionRetried = false;

while (result === undefined) {
try {
// eslint-disable-next-line no-await-in-loop
const contractInstance = await this.getContractInstance(contractName, blockchain);
// eslint-disable-next-line no-await-in-loop
const tx = await this.prepareTransaction(
contractInstance,
Expand Down Expand Up @@ -92,6 +92,25 @@ class NodeBlockchainService extends BlockchainServiceBase {
blockchain.retryTx = true;
// eslint-disable-next-line no-param-reassign
blockchain.previousTxGasPrice = previousTxGasPrice;
} else if (!transactionRetried && /revert|VM Exception/i.test(error.message)) {
let status;
try {
// eslint-disable-next-line no-await-in-loop
status = await contractInstance.methods.status().call();
} catch (_) {
status = false;
}

if (!status) {
// eslint-disable-next-line no-await-in-loop
await this.updateContractInstance(contractName, blockchain, true);
contractInstance = await this.getContractInstance(contractName, blockchain);

Check failure on line 107 in services/blockchain-service/implementations/node-blockchain-service.js

View workflow job for this annotation

GitHub Actions / build

Unexpected `await` inside a loop
transactionRetried = true;
// eslint-disable-next-line no-param-reassign
blockchain.retryTx = true;
} else {
throw error;
}
} else {
throw error;
}
Expand Down
12 changes: 0 additions & 12 deletions services/custom-errors.js

This file was deleted.

0 comments on commit 91513a0

Please sign in to comment.