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

Fix/ Check proper order tx #370

Merged
merged 13 commits into from
Apr 8, 2024
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
"test": "npm run lint && npm run test:unit:cover && npm run test:integration:cover",
"test:unit": "npm run build-tests && npm run mocha \"./dist/test/unit/**/*.test.js\"",
"test:integration": "npm run build-tests && npm run mocha \"./dist/test/integration/**/*.test.js\"",
"test:integration:compute": "npm run build-tests && npm run mocha ./dist/test/integration/compute.test.js",
"test:unit:cover": "nyc --report-dir coverage/unit npm run test:unit",
"test:integration:cover": "nyc --report-dir coverage/integration --no-clean npm run test:integration",
"logs": "./scripts/logs.sh"
Expand Down
2 changes: 0 additions & 2 deletions src/components/core/downloadHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,6 @@ export class DownloadHandler extends Handler {
}
}
}

// 6. Call the validateOrderTransaction function to check order transaction
const paymentValidation = await validateOrderTransaction(
task.transferTxId,
Expand All @@ -327,7 +326,6 @@ export class DownloadHandler extends Handler {
AssetUtils.getServiceIndexById(ddo, task.serviceId),
service.timeout
)

if (paymentValidation.isValid) {
CORE_LOGGER.logMessage(
`Valid payment transaction. Result: ${paymentValidation.message}`,
Expand Down
37 changes: 27 additions & 10 deletions src/components/core/utils/validateOrders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { fetchEventFromTransaction } from '../../../utils/util.js'
import ERC20Template from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20TemplateEnterprise.sol/ERC20TemplateEnterprise.json' assert { type: 'json' }
import ERC721Template from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC721Template.sol/ERC721Template.json' assert { type: 'json' }
import { CORE_LOGGER } from '../../../utils/logging/common.js'
import { EVENTS } from '../../../utils/index.js'

interface ValidateTransactionResponse {
isValid: boolean
Expand Down Expand Up @@ -46,7 +47,6 @@ export async function validateOrderTransaction(
): Promise<ValidateTransactionResponse> {
const contractInterface = new Interface(ERC20Template.abi)
let txReceiptMined = await fetchTransactionReceipt(txId, provider)

if (!txReceiptMined) {
const errorMsg = `Tx receipt cannot be processed, because tx id ${txId} was not mined.`
CORE_LOGGER.logMessage(errorMsg)
Expand All @@ -55,10 +55,17 @@ export async function validateOrderTransaction(
message: errorMsg
}
}
const erc20Address = txReceiptMined.to
const datatokenContract = new Contract(
erc20Address,
ERC20Template.abi,
await provider.getSigner()
)
const erc721Address = await datatokenContract.getERC721Address()

const orderReusedEvent = fetchEventFromTransaction(
txReceiptMined,
'OrderReused',
EVENTS.ORDER_REUSED,
contractInterface
)

Expand All @@ -74,22 +81,32 @@ export async function validateOrderTransaction(
}
}
}

const OrderStartedEvent = fetchEventFromTransaction(
txReceiptMined,
'OrderStarted',
EVENTS.ORDER_STARTED,
contractInterface
)
if (
userAddress.toLowerCase() !== OrderStartedEvent[0].args[0].toLowerCase() &&
userAddress.toLowerCase() !== OrderStartedEvent[0].args[1].toLowerCase()
) {
let orderEvent
for (const event of OrderStartedEvent) {
if (
(userAddress.toLowerCase() === event.args[0].toLowerCase() ||
userAddress.toLowerCase() === event.args[1].toLowerCase()) &&
erc20Address.toLowerCase() === datatokenAddress.toLowerCase() &&
erc721Address.toLowerCase() === dataNftAddress.toLowerCase()
) {
orderEvent = event
break
}
}

if (!orderEvent) {
return {
isValid: false,
message: 'User address does not match with consumer or payer of the transaction.'
message:
'Tx id used not valid, one of the NFT addresses, Datatoken address or the User address contract address does not match.'
}
}
const eventServiceIndex = OrderStartedEvent[0].args[3]
const eventServiceIndex = orderEvent.args[3]

if (BigInt(serviceIndex) !== eventServiceIndex) {
return {
Expand Down
22 changes: 8 additions & 14 deletions src/test/integration/download.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ describe('Should run a complete node flow.', () => {
let publisherAccount: Signer
let consumerAccount: Signer
let consumerAddress: string
let resolvedDDO: Record<string, any>
let orderTxId: string
let assetDID: string
let publishedDataset: any
Expand Down Expand Up @@ -83,10 +82,10 @@ describe('Should run a complete node flow.', () => {
)

config = await getConfiguration(true) // Force reload the configuration
const dbconn = await new Database(config.dbConfig)
oceanNode = await OceanNode.getInstance(dbconn)
database = await new Database(config.dbConfig)
oceanNode = await OceanNode.getInstance(database)
// eslint-disable-next-line no-unused-vars
const indexer = new OceanIndexer(dbconn, mockSupportedNetworks)
const indexer = new OceanIndexer(database, mockSupportedNetworks)

let network = getOceanArtifactsAdressesByChainId(DEVELOPMENT_CHAIN_ID)
if (!network) {
Expand Down Expand Up @@ -200,20 +199,15 @@ describe('Should run a complete node flow.', () => {
assert(orderTxId, 'transaction id not found')
})

it('should download triger download file', function () {
it('should download triger download file', async function () {
this.timeout(DEFAULT_TEST_TIMEOUT * 3)

const doCheck = async () => {
const config = await getConfiguration(true)
database = await new Database(config.dbConfig)
const oceanNode = OceanNode.getInstance(database)
assert(oceanNode, 'Failed to instantiate OceanNode')

const wallet = new ethers.Wallet(
'0xef4b441145c1d0f3b4bc6d61d29f5c6e502359481152f869247c7a4244d45209'
)
const nonce = Date.now().toString()
const message = String(resolvedDDO.id + nonce)
const message = String(publishedDataset.ddo.id + nonce)
const consumerMessage = ethers.solidityPackedKeccak256(
['bytes'],
[ethers.hexlify(ethers.toUtf8Bytes(message))]
Expand All @@ -223,8 +217,8 @@ describe('Should run a complete node flow.', () => {

const downloadTask = {
fileIndex: 0,
documentId: assetDID,
serviceId,
documentId: publishedDataset.ddo.id,
serviceId: publishedDataset.ddo.services[0].id,
transferTxId: orderTxId,
nonce,
consumerAddress,
Expand All @@ -243,7 +237,7 @@ describe('Should run a complete node flow.', () => {
expect(expectedTimeoutFailure(this.test.title)).to.be.equal(true)
}, DEFAULT_TEST_TIMEOUT * 3)

doCheck()
await doCheck()
})
it('should not allow to download the asset with different consumer address', function () {
this.timeout(DEFAULT_TEST_TIMEOUT * 3)
Expand Down
3 changes: 1 addition & 2 deletions src/test/integration/transactionValidation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,7 @@ describe('validateOrderTransaction Function with Orders', () => {
assert(!validationResult.isValid, 'Reuse order transaction should not be valid.')
assert(
validationResult.message ===
'User address does not match with consumer or payer of the transaction.',
'Wrong transaction rejection message'
'Tx id used not valid, one of the NFT addresses, Datatoken address or the User address contract address does not match.'
)
})
after(async () => {
Expand Down
Loading