1
0
mirror of https://github.com/oceanprotocol/market.git synced 2024-12-02 05:57:29 +01:00

wip compute initialize

This commit is contained in:
Bogdan Fazakas 2022-05-12 14:39:14 +03:00
parent ab48abe73c
commit 15af847a9c
4 changed files with 345 additions and 226 deletions

View File

@ -8,7 +8,12 @@ import {
TokensPriceQuery,
TokensPriceQuery_tokens as TokensPrice
} from '../@types/subgraph/TokensPriceQuery'
import { Asset, LoggerInstance, ProviderInstance } from '@oceanprotocol/lib'
import {
Asset,
LoggerInstance,
ProviderFees,
ProviderInstance
} from '@oceanprotocol/lib'
import { AssetExtended } from 'src/@types/AssetExtended'
import { calcInGivenOut } from './pool'
import { getFixedBuyPrice } from './fixedRateExchange'
@ -238,8 +243,7 @@ export async function getOrderPriceAndFees(
asset: AssetExtended,
accountId?: string,
paramsForPool?: CalcInGivenOutParams,
computeEnv: string = null,
computeValidUntil: number = null
providerFees?: ProviderFees
): Promise<OrderPriceAndFees> {
const orderPriceAndFee = {
price: '0',
@ -258,18 +262,16 @@ export async function getOrderPriceAndFees(
// fetch provider fee
const initializeData = await ProviderInstance.initialize(
asset?.id,
asset.services[0].id,
0,
accountId,
asset.services[0].serviceEndpoint,
null,
null,
computeEnv,
computeValidUntil
)
orderPriceAndFee.providerFee = initializeData.providerFee
const initializeData =
!providerFees &&
(await ProviderInstance.initialize(
asset?.id,
asset.services[0].id,
0,
accountId,
asset.services[0].serviceEndpoint
))
orderPriceAndFee.providerFee = providerFees || initializeData.providerFee
// fetch price and swap fees
switch (asset?.accessDetails?.type) {

View File

@ -2,7 +2,11 @@ import {
approve,
Datatoken,
FreOrderParams,
LoggerInstance,
OrderParams,
ProviderComputeInitialize,
ProviderComputeInitializeResults,
ProviderFees,
ProviderInstance
} from '@oceanprotocol/lib'
import { AssetExtended } from 'src/@types/AssetExtended'
@ -15,6 +19,8 @@ import {
consumeMarketOrderFee,
consumeMarketFixedSwapFee
} from '../../app.config'
import { buyDtFromPool } from './pool'
import { toast } from 'react-toastify'
/**
* For pool you need to buy the datatoken beforehand, this always assumes you want to order the first service
@ -31,29 +37,26 @@ export async function order(
asset: AssetExtended,
orderPriceAndFees: OrderPriceAndFees,
accountId: string,
computeEnv: string = null,
computeValidUntil: number = null,
providerFees?: ProviderFees,
computeConsumerAddress?: string
): Promise<TransactionReceipt> {
const datatoken = new Datatoken(web3)
const config = getOceanConfig(asset.chainId)
const initializeData = await ProviderInstance.initialize(
asset.id,
asset.services[0].id,
0,
accountId,
asset.services[0].serviceEndpoint,
null,
null,
computeEnv,
computeValidUntil
)
const initializeData =
!providerFees &&
(await ProviderInstance.initialize(
asset.id,
asset.services[0].id,
0,
accountId,
asset.services[0].serviceEndpoint
))
const orderParams = {
consumer: computeConsumerAddress || accountId,
serviceIndex: 0,
_providerFee: initializeData.providerFee,
_providerFee: providerFees || initializeData.providerFee,
_consumeMarketFee: {
consumeMarketFeeAddress: marketFeeAddress,
consumeMarketFeeAmount: consumeMarketOrderFee,
@ -99,7 +102,7 @@ export async function order(
accountId,
computeConsumerAddress || accountId,
0,
initializeData.providerFee
providerFees || initializeData.providerFee
)
return tx
}
@ -121,10 +124,8 @@ export async function order(
* @param web3
* @param asset
* @param accountId
* @param accountId validOrderTx
* @param computeEnv
* @param computeValidUntil
* @param computeConsumerAddress
* @param validOrderTx
* @param providerFees
* @returns {TransactionReceipt} receipt of the order
*/
export async function reuseOrder(
@ -132,28 +133,27 @@ export async function reuseOrder(
asset: AssetExtended,
accountId: string,
validOrderTx: string,
computeEnv: string = null,
computeValidUntil: number = null,
computeConsumerAddress?: string
) {
providerFees?: ProviderFees
): Promise<TransactionReceipt> {
const datatoken = new Datatoken(web3)
const initializeData = await ProviderInstance.initialize(
asset.id,
asset.services[0].id,
0,
accountId,
asset.services[0].serviceEndpoint,
null,
null,
computeEnv,
computeValidUntil
)
const initializeData =
!providerFees &&
(await ProviderInstance.initialize(
asset.id,
asset.services[0].id,
0,
accountId,
asset.services[0].serviceEndpoint
))
const txApprove = await approve(
web3,
accountId,
initializeData.providerFee.providerFeeToken,
providerFees.providerFeeToken ||
initializeData.providerFee.providerFeeToken,
asset.accessDetails.datatoken.address,
initializeData.providerFee.providerFeeAmount,
providerFees.providerFeeAmount ||
initializeData.providerFee.providerFeeAmount,
false
)
if (!txApprove) {
@ -164,8 +164,62 @@ export async function reuseOrder(
asset.accessDetails.datatoken.address,
accountId,
validOrderTx,
initializeData.providerFee
providerFees || initializeData.providerFee
)
return tx
}
/**
* Handles order for compute assets for the following scenarios:
* - have validOrder and no providerFees -> then order is valid, providerFees are valid, it returns the valid order value
* - have validOrder and providerFees -> then order is valid but providerFees are not valid, we need to call reuseOrder and pay only providerFees
* - no validOrder -> we need to call order, to pay 1 DT & providerFees
* @param web3
* @param asset
* @param accountId
* @param computeEnv
* @param computeValidUntil
* @param computeConsumerAddress
* @returns {Promise<string>} tx id
*/
export async function handleComputeOrder(
web3: Web3,
asset: AssetExtended,
orderPriceAndFees: OrderPriceAndFees,
accountId: string,
hasDatatoken: boolean,
initializeData: ProviderComputeInitialize,
computeConsumerAddress?: string
): Promise<string> {
if (initializeData.validOrder && !initializeData.providerFee) {
return initializeData.validOrder
} else if (initializeData.validOrder) {
const tx = await reuseOrder(
web3,
asset,
accountId,
initializeData.validOrder,
initializeData.providerFee
)
return tx.transactionHash
} else {
if (!hasDatatoken && asset?.accessDetails.type === 'dynamic') {
const poolTx = await buyDtFromPool(asset?.accessDetails, accountId, web3)
LoggerInstance.log('[compute] Buy dt from pool: ', poolTx)
if (!poolTx) {
toast.error('Failed to buy datatoken from pool!')
return
}
}
const tx = await order(
web3,
asset,
orderPriceAndFees,
accountId,
initializeData.providerFee,
computeConsumerAddress
)
return tx.transactionHash
}
}

View File

@ -1,11 +1,50 @@
import {
ComputeAlgorithm,
ComputeAsset,
ComputeEnvironment,
downloadFileBrowser,
FileMetadata,
LoggerInstance,
ProviderComputeInitializeResults,
ProviderInstance
} from '@oceanprotocol/lib'
import { da } from 'date-fns/locale'
import { AssetExtended } from 'src/@types/AssetExtended'
import Web3 from 'web3'
import { getValidUntilTime } from './compute'
export async function initializeProviderForCompute(
dataset: AssetExtended,
algorithm: AssetExtended,
accountId: string,
computeEnv: ComputeEnvironment = null
): Promise<ProviderComputeInitializeResults> {
const computeAsset: ComputeAsset = {
documentId: dataset.id,
serviceId: dataset.services[0].id,
transferTxId: dataset.accessDetails.validOrderTx
}
const computeAlgo: ComputeAlgorithm = {
documentId: algorithm.id,
serviceId: algorithm.services[0].id,
transferTxId: algorithm.accessDetails.validOrderTx
}
const validUntil = getValidUntilTime(
computeEnv?.maxJobDuration,
dataset.services[0].timeout,
algorithm.services[0].timeout
)
return await ProviderInstance.initializeCompute(
[computeAsset],
computeAlgo,
computeEnv?.id,
validUntil,
dataset.services[0].serviceEndpoint,
accountId
)
}
// TODO: Why do we have these one line functions ?!?!?!
export async function getEncryptedFiles(

View File

@ -10,7 +10,8 @@ import {
ComputeEnvironment,
LoggerInstance,
ComputeAlgorithm,
ComputeOutput
ComputeOutput,
ProviderComputeInitializeResults
} from '@oceanprotocol/lib'
import { toast } from 'react-toastify'
import Price from '@shared/Price'
@ -27,9 +28,7 @@ import {
isOrderable,
getAlgorithmAssetSelectionList,
getAlgorithmsForAsset,
getValidUntilTime,
getComputeEnviroment,
checkComputeResourcesValidity
getComputeEnviroment
} from '@utils/compute'
import { AssetSelectionAsset } from '@shared/FormFields/AssetSelection'
import AlgorithmDatasetsListForCompute from './AlgorithmDatasetsListForCompute'
@ -42,13 +41,14 @@ import { useAbortController } from '@hooks/useAbortController'
import { getOrderPriceAndFees } from '@utils/accessDetailsAndPricing'
import { OrderPriceAndFees } from 'src/@types/Price'
import { buyDtFromPool } from '@utils/pool'
import { order, reuseOrder } from '@utils/order'
import { handleComputeOrder, order, reuseOrder } from '@utils/order'
import { AssetExtended } from 'src/@types/AssetExtended'
import { getComputeFeedback } from '@utils/feedback'
import { usePool } from '@context/Pool'
import { useMarketMetadata } from '@context/MarketMetadata'
import { getPoolData } from '@context/Pool/_utils'
import { getDummyWeb3 } from '@utils/web3'
import { initializeProviderForCompute } from '@utils/provider'
export default function Compute({
asset,
@ -84,7 +84,7 @@ export default function Compute({
const [validAlgorithmOrderTx, setValidAlgorithmOrderTx] = useState('')
const hasDatatoken = Number(dtBalance) >= 1
const isMounted = useIsMounted()
// const isMounted = useIsMounted()
const { getOpcFeeForToken } = useMarketMetadata()
const { poolData } = usePool()
const newCancelToken = useCancelToken()
@ -92,7 +92,9 @@ export default function Compute({
const [isAlgoConsumablePrice, setIsAlgoConsumablePrice] = useState(true)
const [computeStatusText, setComputeStatusText] = useState('')
const [computeEnv, setComputeEnv] = useState<ComputeEnvironment>()
const [computeValidUntil, setComputeValidUntil] = useState<number>()
const [initializedProviderResponse, setInitializedProviderResponse] =
useState<ProviderComputeInitializeResults>()
// const [computeValidUntil, setComputeValidUntil] = useState<number>()
const [datasetOrderPriceAndFees, setDatasetOrderPriceAndFees] =
useState<OrderPriceAndFees>()
const [isRequestingDataseOrderPrice, setIsRequestingDataseOrderPrice] =
@ -101,7 +103,7 @@ export default function Compute({
useState<OrderPriceAndFees>()
const [isRequestingAlgoOrderPrice, setIsRequestingAlgoOrderPrice] =
useState(false)
const [isProviderFeeValid, setIsProviderFeeValid] = useState(false)
// const [isProviderFeeValid, setIsProviderFeeValid] = useState(false)
const isComputeButtonDisabled =
isJobStarting === true ||
file === null ||
@ -125,21 +127,35 @@ export default function Compute({
async function initPriceAndFees() {
const computeEnv = await getComputeEnviroment(asset)
setComputeEnv(computeEnv)
setIsProviderFeeValid(
await checkComputeResourcesValidity(
asset,
accountId,
computeEnv?.maxJobDuration,
asset.services[0].timeout,
selectedAlgorithmAsset.services[0].timeout
)
const initializedProvider = await initializeProviderForCompute(
asset,
selectedAlgorithmAsset,
accountId,
computeEnv
)
const validUntil = getValidUntilTime(
computeEnv?.maxJobDuration,
asset.services[0].timeout,
selectedAlgorithmAsset.services[0].timeout
)
setComputeValidUntil(validUntil)
setInitializedProviderResponse(initializedProvider)
// setIsProviderFeeValid(
// await checkComputeResourcesValidity(
// asset,
// accountId,
// computeEnv?.maxJobDuration,
// asset.services[0].timeout,
// selectedAlgorithmAsset.services[0].timeout
// )
// )
// let datasetOrderTx = await checkComputeResourcesValidity(
// dataset,
// accountId,
// computeEnv?.maxJobDuration,
// asset.services[0].timeout,
// selectedAlgorithmAsset.services[0].timeout
// )
// const validUntil = getValidUntilTime(
// computeEnv?.maxJobDuration,
// asset.services[0].timeout,
// selectedAlgorithmAsset.services[0].timeout
// )
// setComputeValidUntil(validUntil)
if (
asset?.accessDetails?.addressOrId !== ZERO_ADDRESS ||
asset?.accessDetails?.type !== 'free'
@ -172,10 +188,8 @@ export default function Compute({
asset,
ZERO_ADDRESS,
poolParams,
computeEnv?.id,
validUntil
initializedProvider.datasets[0].providerFee
)
console.log('datasetPriceAndFees price and fees', datasetPriceAndFees)
if (!datasetPriceAndFees) {
setError('Error setting dataset price and fees!')
toast.error('Error setting dataset price and fees!')
@ -223,15 +237,13 @@ export default function Compute({
selectedAlgorithmAsset,
ZERO_ADDRESS,
algoPoolParams,
computeEnv?.id,
validUntil
initializedProvider.algorithm.providerFee
)
if (!algorithmOrderPriceAndFees) {
setError('Error setting algorithm price and fees!')
toast.error('Error setting algorithm price and fees!')
return
}
console.log('algo price and fees', algorithmOrderPriceAndFees)
setAlgoOrderPriceAndFees(algorithmOrderPriceAndFees)
setIsRequestingAlgoOrderPrice(false)
}
@ -246,7 +258,6 @@ export default function Compute({
}, [asset?.accessDetails])
useEffect(() => {
console.log('selcted algo', selectedAlgorithmAsset)
if (!selectedAlgorithmAsset?.accessDetails || !accountId) return
setIsConsumablePrice(selectedAlgorithmAsset?.accessDetails?.isPurchasable)
@ -311,153 +322,166 @@ export default function Compute({
return
}
let datasetOrderTx
if (isOwned) {
datasetOrderTx = validOrderTx
LoggerInstance.log('[compute] Dataset owned txId:', validOrderTx)
} else {
try {
if (!hasDatatoken && asset?.accessDetails.type === 'dynamic') {
setComputeStatusText(
getComputeFeedback(
asset.accessDetails.baseToken?.symbol,
asset.accessDetails.datatoken?.symbol,
asset.metadata.type
)[1]
)
const tx = await buyDtFromPool(
asset?.accessDetails,
accountId,
web3
)
LoggerInstance.log('[compute] Buy dataset dt from pool: ', tx)
if (!tx) {
toast.error('Failed to buy datatoken from pool!')
return
}
}
LoggerInstance.log(
'dataset orderPriceAndFees: ',
datasetOrderPriceAndFees
)
setComputeStatusText(
getComputeFeedback(
asset.accessDetails.baseToken?.symbol,
asset.accessDetails.datatoken?.symbol,
asset.metadata.type
)[asset.accessDetails?.type === 'fixed' ? 3 : 2]
)
const orderTx = await order(
web3,
asset,
datasetOrderPriceAndFees,
accountId,
computeEnv?.id,
computeValidUntil,
computeEnv?.consumerAddress
)
if (!orderTx) {
toast.error('Failed to order dataset asset!')
return
}
LoggerInstance.log(
'[compute] Order dataset: ',
orderTx.transactionHash
)
setIsOwned(true)
setValidOrderTx(orderTx.transactionHash)
datasetOrderTx = orderTx.transactionHash
} catch (e) {
LoggerInstance.log(e.message)
toast.error('Failed to order dataset asset!')
return
}
}
const datasetOrderTx = await handleComputeOrder(
web3,
asset,
datasetOrderPriceAndFees,
accountId,
hasDatatoken,
initializedProviderResponse.datasets[0],
computeEnv.consumerAddress
)
// if (isOwned) {
// datasetOrderTx = validOrderTx
// LoggerInstance.log('[compute] Dataset owned txId:', validOrderTx)
// } else {
// try {
// if (!hasDatatoken && asset?.accessDetails.type === 'dynamic') {
// setComputeStatusText(
// getComputeFeedback(
// asset.accessDetails.baseToken?.symbol,
// asset.accessDetails.datatoken?.symbol,
// asset.metadata.type
// )[1]
// )
// const tx = await buyDtFromPool(
// asset?.accessDetails,
// accountId,
// web3
// )
// LoggerInstance.log('[compute] Buy dataset dt from pool: ', tx)
// if (!tx) {
// toast.error('Failed to buy datatoken from pool!')
// return
// }
// }
// LoggerInstance.log(
// 'dataset orderPriceAndFees: ',
// datasetOrderPriceAndFees
// )
// setComputeStatusText(
// getComputeFeedback(
// asset.accessDetails.baseToken?.symbol,
// asset.accessDetails.datatoken?.symbol,
// asset.metadata.type
// )[asset.accessDetails?.type === 'fixed' ? 3 : 2]
// )
// const orderTx = await order(
// web3,
// asset,
// datasetOrderPriceAndFees,
// accountId, )
// if (!orderTx) {
// toast.error('Failed to order dataset asset!')
// return
// }
// LoggerInstance.log(
// '[compute] Order dataset: ',
// orderTx.transactionHash
// )
// setIsOwned(true)
// setValidOrderTx(orderTx.transactionHash)
// datasetOrderTx = orderTx.transactionHash
// } catch (e) {
// LoggerInstance.log(e.message)
// toast.error('Failed to order dataset asset!')
// return
// }
// }
let algorithmOrderTx
if (isAlgorithmOwned) {
algorithmOrderTx = validAlgorithmOrderTx
LoggerInstance.log(
'[compute] Algorithm owned txId:',
validAlgorithmOrderTx
)
} else {
try {
if (
!hasAlgoAssetDatatoken &&
selectedAlgorithmAsset?.accessDetails?.type === 'dynamic'
) {
setComputeStatusText(
getComputeFeedback(
selectedAlgorithmAsset.accessDetails.baseToken?.symbol,
selectedAlgorithmAsset.accessDetails.datatoken?.symbol,
selectedAlgorithmAsset.metadata.type
)[1]
)
const tx = await buyDtFromPool(
selectedAlgorithmAsset?.accessDetails,
accountId,
web3
)
LoggerInstance.log('[compute] Buy algorithm dt from pool: ', tx)
if (!tx) {
toast.error('Failed to buy datatoken from pool!')
return
}
}
setComputeStatusText(
getComputeFeedback(
selectedAlgorithmAsset.accessDetails.baseToken?.symbol,
selectedAlgorithmAsset.accessDetails.datatoken?.symbol,
selectedAlgorithmAsset.metadata.type
)[selectedAlgorithmAsset.accessDetails?.type === 'fixed' ? 3 : 2]
)
const orderTx = await order(
web3,
selectedAlgorithmAsset,
algoOrderPriceAndFees,
accountId,
computeEnv?.id,
computeValidUntil,
computeEnv?.consumerAddress
)
if (!orderTx) {
toast.error('Failed to order algorithm asset!')
return
}
LoggerInstance.log(
'[compute] Order algorithm: ',
orderTx.transactionHash
)
setIsAlgorithmOwned(true)
setValidAlgorithmOrderTx(orderTx.transactionHash)
algorithmOrderTx = orderTx.transactionHash
} catch (e) {
LoggerInstance.log(e.message)
toast.error('Failed to order algorithm asset!')
return
}
}
const algorithmOrderTx = await handleComputeOrder(
web3,
selectedAlgorithmAsset,
datasetOrderPriceAndFees,
accountId,
hasDatatoken,
initializedProviderResponse.algorithm,
computeEnv.consumerAddress
)
if (isOwned && !isProviderFeeValid) {
const reuseOrderTx = await reuseOrder(
web3,
asset,
accountId,
validOrderTx,
computeEnv?.id,
computeValidUntil
)
if (!reuseOrderTx) {
toast.error('Failed to pay provider fees!')
return
}
LoggerInstance.log(
'[compute] Reused order: ',
reuseOrderTx.transactionHash
)
datasetOrderTx = reuseOrderTx.transactionHash
}
// if (isAlgorithmOwned) {
// algorithmOrderTx = validAlgorithmOrderTx
// LoggerInstance.log(
// '[compute] Algorithm owned txId:',
// validAlgorithmOrderTx
// )
// } else {
// try {
// if (
// !hasAlgoAssetDatatoken &&
// selectedAlgorithmAsset?.accessDetails?.type === 'dynamic'
// ) {
// setComputeStatusText(
// getComputeFeedback(
// selectedAlgorithmAsset.accessDetails.baseToken?.symbol,
// selectedAlgorithmAsset.accessDetails.datatoken?.symbol,
// selectedAlgorithmAsset.metadata.type
// )[1]
// )
// const tx = await buyDtFromPool(
// selectedAlgorithmAsset?.accessDetails,
// accountId,
// web3
// )
// LoggerInstance.log('[compute] Buy algorithm dt from pool: ', tx)
// if (!tx) {
// toast.error('Failed to buy datatoken from pool!')
// return
// }
// }
// setComputeStatusText(
// getComputeFeedback(
// selectedAlgorithmAsset.accessDetails.baseToken?.symbol,
// selectedAlgorithmAsset.accessDetails.datatoken?.symbol,
// selectedAlgorithmAsset.metadata.type
// )[selectedAlgorithmAsset.accessDetails?.type === 'fixed' ? 3 : 2]
// )
// const orderTx = await order(
// web3,
// selectedAlgorithmAsset,
// algoOrderPriceAndFees,
// accountId,
// computeEnv?.id,
// computeValidUntil,
// computeEnv?.consumerAddress
// )
// if (!orderTx) {
// toast.error('Failed to order algorithm asset!')
// return
// }
// LoggerInstance.log(
// '[compute] Order algorithm: ',
// orderTx.transactionHash
// )
// setIsAlgorithmOwned(true)
// setValidAlgorithmOrderTx(orderTx.transactionHash)
// algorithmOrderTx = orderTx.transactionHash
// } catch (e) {
// LoggerInstance.log(e.message)
// toast.error('Failed to order algorithm asset!')
// return
// }
// }
// if (isOwned && !isProviderFeeValid) {
// const reuseOrderTx = await reuseOrder(
// web3,
// asset,
// accountId,
// validOrderTx,
// computeEnv?.id,
// computeValidUntil
// )
// if (!reuseOrderTx) {
// toast.error('Failed to pay provider fees!')
// return
// }
// LoggerInstance.log(
// '[compute] Reused order: ',
// reuseOrderTx.transactionHash
// )
// datasetOrderTx = reuseOrderTx.transactionHash
// }
LoggerInstance.log('[compute] Starting compute job.')
const computeAsset: ComputeAsset = {