Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion config.json
Original file line number Diff line number Diff line change
Expand Up @@ -147,4 +147,4 @@
}
}
]
}
}
10 changes: 5 additions & 5 deletions src/components/c2d/compute_engine_docker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ export class C2DEngineDocker extends C2DEngine {
envConfig.fees[feeChain][i].prices.length > 0
) {
if (!envConfig.fees[feeChain][i].feeToken) {
const tokenAddress = await getOceanTokenAddressForChain(parseInt(feeChain))
const tokenAddress = getOceanTokenAddressForChain(parseInt(feeChain))
if (tokenAddress) {
envConfig.fees[feeChain][i].feeToken = tokenAddress
tmpFees.push(envConfig.fees[feeChain][i])
Expand Down Expand Up @@ -937,7 +937,7 @@ export class C2DEngineDocker extends C2DEngine {
}
// resources are now available, let's start the job
const { algorithm } = job
if (algorithm.meta.container && algorithm.meta.container.dockerfile) {
if (algorithm?.meta.container && algorithm?.meta.container.dockerfile) {
job.status = C2DStatusNumber.BuildImage
job.statusText = C2DStatusText.BuildImage
this.buildImage(job, null)
Expand Down Expand Up @@ -1040,7 +1040,7 @@ export class C2DEngineDocker extends C2DEngine {
containerInfo.HostConfig.IpcMode = advancedConfig.IpcMode
if (advancedConfig.ShmSize)
containerInfo.HostConfig.ShmSize = advancedConfig.ShmSize
if (job.algorithm.meta.container.entrypoint) {
if (job.algorithm?.meta.container.entrypoint) {
const newEntrypoint = job.algorithm.meta.container.entrypoint.replace(
'$ALGO',
'data/transformations/algorithm'
Expand Down Expand Up @@ -1338,7 +1338,7 @@ export class C2DEngineDocker extends C2DEngine {
// console.error('Container not found! ' + e.message)
}
try {
const volume = await this.docker.getVolume(job.jobId + '-volume')
const volume = this.docker.getVolume(job.jobId + '-volume')
if (volume) {
try {
await volume.remove()
Expand All @@ -1349,7 +1349,7 @@ export class C2DEngineDocker extends C2DEngine {
} catch (e) {
// console.error('Container volume not found! ' + e.message)
}
if (job.algorithm.meta.container && job.algorithm.meta.container.dockerfile) {
if (job.algorithm?.meta.container && job.algorithm?.meta.container.dockerfile) {
const image = getAlgorithmImage(job.algorithm, job.jobId)
if (image) {
try {
Expand Down
89 changes: 61 additions & 28 deletions src/components/core/utils/escrow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { EscrowAuthorization, EscrowLock } from '../../../@types/Escrow.js'
import { getOceanArtifactsAdressesByChainId } from '../../../utils/address.js'
import { RPCS } from '../../../@types/blockchain.js'
import { create256Hash } from '../../../utils/crypt.js'
import { sleep } from '../../../utils/util.js'
export class Escrow {
private networks: RPCS
private claimDurationTimeout: number
Expand All @@ -14,7 +15,7 @@ export class Escrow {
}

// eslint-disable-next-line require-await
async getEscrowContractAddressForChain(chainId: number): Promise<string | null> {
getEscrowContractAddressForChain(chainId: number): string | null {
const addresses = getOceanArtifactsAdressesByChainId(chainId)
if (addresses && addresses.Escrow) return addresses.Escrow
return null
Expand All @@ -24,9 +25,17 @@ export class Escrow {
return maxJobDuration + this.claimDurationTimeout
}

async getPaymentAmountInWei(cost: number, chain: number, token: string) {
async getPaymentAmountInWei(
cost: number,
chain: number,
token: string,
existingChain?: Blockchain
) {
const { rpc, network, chainId, fallbackRPCs } = this.networks[chain]
const blockchain = new Blockchain(rpc, network, chainId, fallbackRPCs)
let blockchain: Blockchain = existingChain
if (!blockchain) {
blockchain = new Blockchain(rpc, network, chainId, fallbackRPCs)
}
const provider = blockchain.getProvider()

const decimalgBigNumber = await getDatatokenDecimals(token, provider)
Expand All @@ -46,24 +55,25 @@ export class Escrow {
}

// eslint-disable-next-line require-await
async getContract(
chainId: number,
signer: ethers.Signer
): Promise<ethers.Contract | null> {
const address = await this.getEscrowContractAddressForChain(chainId)
getContract(chainId: number, signer: ethers.Signer): ethers.Contract | null {
const address = this.getEscrowContractAddressForChain(chainId)
if (!address) return null
return new ethers.Contract(address, EscrowJson.abi, signer)
}

async getUserAvailableFunds(
chain: number,
payer: string,
token: string
token: string,
existingChain?: Blockchain
): Promise<BigInt> {
const { rpc, network, chainId, fallbackRPCs } = this.networks[chain]
const blockchain = new Blockchain(rpc, network, chainId, fallbackRPCs)
let blockchain: Blockchain = existingChain
if (!blockchain) {
blockchain = new Blockchain(rpc, network, chainId, fallbackRPCs)
}
const signer = blockchain.getSigner()
const contract = await this.getContract(chainId, signer)
const contract = this.getContract(chainId, signer)
try {
const funds = await contract.getUserFunds(payer, token)
return funds.available
Expand All @@ -81,7 +91,7 @@ export class Escrow {
const { rpc, network, chainId, fallbackRPCs } = this.networks[chain]
const blockchain = new Blockchain(rpc, network, chainId, fallbackRPCs)
const signer = blockchain.getSigner()
const contract = await this.getContract(chainId, signer)
const contract = this.getContract(chainId, signer)
try {
return await contract.getLocks(token, payer, payee)
} catch (e) {
Expand All @@ -93,12 +103,16 @@ export class Escrow {
chain: number,
token: string,
payer: string,
payee: string
payee: string,
existingChain?: Blockchain
): Promise<EscrowAuthorization[]> {
const { rpc, network, chainId, fallbackRPCs } = this.networks[chain]
const blockchain = new Blockchain(rpc, network, chainId, fallbackRPCs)
let blockchain: Blockchain = existingChain
if (!blockchain) {
blockchain = new Blockchain(rpc, network, chainId, fallbackRPCs)
}
const signer = blockchain.getSigner()
const contract = await this.getContract(chainId, signer)
const contract = this.getContract(chainId, signer)
try {
return await contract.getAuthorizations(token, payer, payee)
} catch (e) {
Expand All @@ -118,24 +132,43 @@ export class Escrow {
const { rpc, network, chainId, fallbackRPCs } = this.networks[chain]
const blockchain = new Blockchain(rpc, network, chainId, fallbackRPCs)
const signer = blockchain.getSigner()
const contract = await this.getContract(chainId, signer)
const contract = this.getContract(chainId, signer)
if (!contract) throw new Error(`Failed to initialize escrow contract`)
const wei = await this.getPaymentAmountInWei(amount, chain, token)
const userBalance = await this.getUserAvailableFunds(chain, payer, token)
const wei = await this.getPaymentAmountInWei(amount, chain, token, blockchain)
const userBalance = await this.getUserAvailableFunds(chain, payer, token, blockchain)
if (BigInt(userBalance.toString()) < BigInt(wei)) {
// not enough funds
throw new Error(`User ${payer} does not have enough funds`)
}

const auths = await this.getAuthorizations(
chain,
token,
payer,
await signer.getAddress()
)
const signerAddress = await signer.getAddress()

let retries = 2
let auths: EscrowAuthorization[] = []
while (retries > 0) {
auths = await this.getAuthorizations(chain, token, payer, signerAddress, blockchain)
if (!auths || auths.length !== 1) {
console.log(
`No escrow auths found for: chain=${chain}, token=${token}, payer=${payer}, nodeAddress=${signerAddress}. Found ${
auths?.length || 0
} authorizations. ${retries > 0 ? 'Retrying..' : ''}`
)
} else if (auths && auths.length === 1) {
break
}
if (retries > 1) {
await sleep(1000)
}
retries--
}
if (!auths || auths.length !== 1) {
throw new Error(`No escrow auths found`)
throw new Error(
`No escrow auths found for: chain=${chain}, token=${token}, payer=${payer}, nodeAddress=${signerAddress}. Found ${
auths?.length || 0
} authorizations.`
)
}

if (
BigInt(auths[0].currentLockedAmount.toString()) + BigInt(wei) >
BigInt(auths[0].maxLockedAmount.toString())
Expand Down Expand Up @@ -173,8 +206,8 @@ export class Escrow {
const { rpc, network, chainId, fallbackRPCs } = this.networks[chain]
const blockchain = new Blockchain(rpc, network, chainId, fallbackRPCs)
const signer = blockchain.getSigner()
const contract = await this.getContract(chainId, signer)
const wei = await this.getPaymentAmountInWei(amount, chain, token)
const contract = this.getContract(chainId, signer)
const wei = await this.getPaymentAmountInWei(amount, chain, token, blockchain)
const jobId = create256Hash(job)
if (!contract) return null
try {
Expand Down Expand Up @@ -216,7 +249,7 @@ export class Escrow {
const blockchain = new Blockchain(rpc, network, chainId, fallbackRPCs)
const signer = blockchain.getSigner()
const jobId = create256Hash(job)
const contract = await this.getContract(chainId, signer)
const contract = this.getContract(chainId, signer)

if (!contract) return null
try {
Expand Down
3 changes: 1 addition & 2 deletions src/utils/address.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ export function getOceanArtifactsAdresses(): any {
*/
export function getOceanArtifactsAdressesByChainId(chain: number): any {
try {
// eslint-disable-next-line security/detect-non-literal-fs-filename
const data = getOceanArtifactsAdresses()
if (data) {
const networks = Object.keys(data)
Expand All @@ -53,7 +52,7 @@ export function getOceanArtifactsAdressesByChainId(chain: number): any {
}

// eslint-disable-next-line require-await
export function getOceanTokenAddressForChain(chainId: number): Promise<string | null> {
export function getOceanTokenAddressForChain(chainId: number): string | null {
const addresses = getOceanArtifactsAdressesByChainId(chainId)
if (addresses && addresses.Ocean) return addresses.Ocean
return null
Expand Down
28 changes: 24 additions & 4 deletions src/utils/blockchain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ const MUMBAI_NETWORK_ID = 80001
const SEPOLIA_NETWORK_ID = 11155111

export class Blockchain {
private static signers: Map<string, Signer> = new Map()
private static providers: Map<string, JsonRpcApiProvider> = new Map()
private signer: Signer
private provider: JsonRpcApiProvider
private chainId: number
Expand All @@ -46,12 +48,30 @@ export class Blockchain {
}
this.network = new ethers.Network(chainName, chainId)
// this.provider = new ethers.JsonRpcProvider(rpc, this.network)
this.provider = new ethers.JsonRpcProvider(rpc, null, {
staticNetwork: ethers.Network.from(chainId)
})
const providerKey = `${chainId}-${rpc}`
if (Blockchain.providers.has(providerKey)) {
this.provider = Blockchain.providers.get(providerKey)
} else {
this.provider = new ethers.JsonRpcProvider(rpc, null, {
staticNetwork: ethers.Network.from(chainId)
})
Blockchain.providers.set(providerKey, this.provider)
}

this.registerForNetworkEvents()
// always use this signer, not simply provider.getSigner(0) for instance (as we do on many tests)
this.signer = new ethers.Wallet(process.env.PRIVATE_KEY, this.provider)
const signerKey = `${chainId}-${process.env.PRIVATE_KEY}`
if (Blockchain.signers.has(signerKey)) {
let cachedSigner = Blockchain.signers.get(signerKey)
if (cachedSigner.provider !== this.provider) {
cachedSigner = (cachedSigner as ethers.Wallet).connect(this.provider)
Blockchain.signers.set(signerKey, cachedSigner)
}
this.signer = cachedSigner
} else {
this.signer = new ethers.Wallet(process.env.PRIVATE_KEY, this.provider)
Blockchain.signers.set(signerKey, this.signer)
}
}

public getSigner(): Signer {
Expand Down
Loading