Skip to content

Commit

Permalink
move superfluid logic into InstanceManager; rename `getStreamCostPerH…
Browse files Browse the repository at this point in the history
…our` to `getHours` and use beta CCN API for testing
  • Loading branch information
MHHukiewitz committed Jan 23, 2024
1 parent d7292aa commit 45cb088
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 49 deletions.
20 changes: 15 additions & 5 deletions src/domain/executable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { VolumeField } from '@/hooks/form/useAddVolume'
import { DomainField } from '@/hooks/form/useAddDomains'
import { Domain, DomainManager } from './domain'
import { EntityType, PaymentMethod } from '@/helpers/constants'
import { getStreamCostPerHour, StreamDurationField } from '@/hooks/form/useSelectStreamDuration'
import { getHours, StreamDurationField } from '@/hooks/form/useSelectStreamDuration'

type ExecutableCapabilitiesProps = {
internetAccess?: boolean
Expand All @@ -38,12 +38,22 @@ export type ExecutableCost = Omit<VolumeCost, 'totalCost'> & {
totalStreamCost: number
}

export type PaymentConfiguration = {
export type HoldPaymentConfiguration = {
chain: Chain
type: PaymentMethod
receiver?: string
type: PaymentMethod.Hold
}

export type StreamPaymentConfiguration = {
chain: Chain
type: PaymentMethod.Stream
sender: string
receiver: string
streamCost: number
streamDuration: StreamDurationField
}

export type PaymentConfiguration = HoldPaymentConfiguration | StreamPaymentConfiguration

export abstract class Executable {
/**
* Calculates the amount of tokens required to deploy a function
Expand Down Expand Up @@ -93,7 +103,7 @@ export abstract class Executable {

const streamCostPerHour =
paymentMethod === PaymentMethod.Stream && streamDuration
? getStreamCostPerHour(streamDuration)
? getHours(streamDuration)
: Number.POSITIVE_INFINITY

const totalStreamCost = totalCost * streamCostPerHour
Expand Down
79 changes: 65 additions & 14 deletions src/domain/instance.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import { Account } from 'aleph-sdk-ts/dist/accounts/account'
import { forget, instance, any } from 'aleph-sdk-ts/dist/messages'
import { any, forget, instance } from 'aleph-sdk-ts/dist/messages'
import { InstancePublishConfiguration } from 'aleph-sdk-ts/dist/messages/instance/publish'
import { MachineVolume, MessageType, InstanceContent } from 'aleph-sdk-ts/dist/messages/types'
import { InstanceContent, MachineVolume, MessageType, PaymentType } from 'aleph-sdk-ts/dist/messages/types'
import E_ from '../helpers/errors'
import {
EntityType,
apiServer,
defaultInstanceChannel, PaymentMethod,
} from '../helpers/constants'
import { apiServer, defaultInstanceChannel, EntityType, PaymentMethod } from '../helpers/constants'
import { getDate, getExplorerURL } from '../helpers/utils'
import { EnvVarField } from '@/hooks/form/useAddEnvVars'
import { InstanceSpecsField } from '@/hooks/form/useSelectInstanceSpecs'
import { SSHKeyField } from '@/hooks/form/useAddSSHKeys'
import { Executable, ExecutableCost, ExecutableCostProps, PaymentConfiguration } from './executable'
import {
Executable,
ExecutableCost,
ExecutableCostProps,
PaymentConfiguration,
StreamPaymentConfiguration,
} from './executable'
import { VolumeField } from '@/hooks/form/useAddVolume'
import { InstanceImageField } from '@/hooks/form/useSelectInstanceImage'
import { FileManager } from './file'
Expand All @@ -21,11 +23,11 @@ import { VolumeManager } from './volume'
import { DomainField } from '@/hooks/form/useAddDomains'
import { DomainManager } from './domain'
import { EntityManager } from './types'
import {
instanceSchema,
instanceStreamSchema,
} from '@/helpers/schemas/instance'
import { instanceSchema, instanceStreamSchema } from '@/helpers/schemas/instance'
import { NameAndTagsField } from '@/hooks/form/useAddNameAndTags'
import { Web3Provider } from '@ethersproject/providers'
import { superfluid } from 'aleph-sdk-ts/dist/accounts'
import { getHours } from '@/hooks/form/useSelectStreamDuration'

export type AddInstance = Omit<
InstancePublishConfiguration,
Expand Down Expand Up @@ -131,6 +133,26 @@ export class InstanceManager
try {
const instanceMessage = await this.parseInstance(newInstance)

if (newInstance.payment?.type === PaymentMethod.Stream) {
const { streamCost, streamDuration, sender, receiver } = newInstance.payment
const web3Provider = new Web3Provider(window.ethereum)

const superfluidAccount = new superfluid.SuperfluidAccount(
web3Provider,
sender,
)
await superfluidAccount.init()
await superfluidAccount.decreaseALEPHxFlow(receiver, 10)
const alephxBalance = await superfluidAccount.getALEPHxBalance()
const alephxFlow = await superfluidAccount.getALEPHxFlow(receiver)
const usedAlephInDuration = alephxFlow.mul(getHours(streamDuration))
const totalRequiredAleph = usedAlephInDuration.add(streamCost)
if (alephxBalance.lt(totalRequiredAleph)) {
throw new Error(`Insufficient balance: ${totalRequiredAleph.sub(alephxBalance).toString()} ALEPH required. Try to lower the VM cost or the duration.`)
}
await superfluidAccount.increaseALEPHxFlow(receiver, streamCost / getHours(streamDuration))
}

const response = await instance.publish({
...instanceMessage,
APIServer: apiServer,
Expand All @@ -148,8 +170,37 @@ export class InstanceManager
}

async del(instanceOrId: string | Instance): Promise<void> {
instanceOrId =
typeof instanceOrId === 'string' ? instanceOrId : instanceOrId.id
let instance: Instance | undefined
if (typeof instanceOrId !== 'string') {
instance = instanceOrId
instanceOrId = instance.id
} else {
instance = await this.get(instanceOrId)
}

if (!instance) throw new Error('Invalid instance ID')

if (instance.payment?.type === PaymentType.superfluid) {
const { sender, receiver } = instance.payment as StreamPaymentConfiguration
const instanceCosts = await InstanceManager.getCost({
paymentMethod: PaymentMethod.Stream,
specs: {
cpu: instance.resources.vcpus,
memory: instance.resources.memory,
storage: instance.volumes.reduce((ac, cv) => ac + cv["size_mb"] ?? 0, 0),
ram: instance.resources.memory,
}
})
console.log("instanceCosts", instanceCosts)
const web3Provider = new Web3Provider(window.ethereum)

const superfluidAccount = new superfluid.SuperfluidAccount(
web3Provider,
sender,
)
await superfluidAccount.init()
await superfluidAccount.decreaseALEPHxFlow(receiver, instanceCosts.totalStreamCost)
}

try {
await forget.Publish({
Expand Down
4 changes: 2 additions & 2 deletions src/helpers/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ export const channel = 'FOUNDATION'
export const tags = ['mainnet']
export const postType = 'corechan-operation'

export const apiServer = 'https://api3.aleph.im'
export const wsServer = 'wss://api3.aleph.im'
export const apiServer = 'http://pyaleph-lab-2.aleph.cloud:4024'
export const wsServer = 'ws://pyaleph-lab-2.aleph.cloud:4024'
export const mbPerAleph = 3

export const scoringAddress = '0x4D52380D3191274a04846c89c069E6C3F2Ed94e4'
Expand Down
4 changes: 2 additions & 2 deletions src/hooks/form/useSelectInstanceSpecs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export type InstanceSpecsField = {

export function updateSpecsStorage(
specs: InstanceSpecsField,
isPersistent: boolean,
isPersistent: boolean = true,
): InstanceSpecsField {
return {
...specs,
Expand All @@ -27,7 +27,7 @@ export function updateSpecsStorage(

// @note: https://medium.com/aleph-im/aleph-im-tokenomics-update-nov-2022-fd1027762d99
export function getDefaultSpecsOptions(
isPersistent: boolean,
isPersistent: boolean = true,
): InstanceSpecsField[] {
return [1, 2, 4, 6, 8, 12].map((cpu) =>
updateSpecsStorage(
Expand Down
2 changes: 1 addition & 1 deletion src/hooks/form/useSelectStreamDuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export type StreamDurationField = {
unit: StreamDurationUnit
}

export function getStreamCostPerHour(
export function getHours(
streamDuration: StreamDurationField,
): number {
if (!streamDuration) return 0
Expand Down
28 changes: 3 additions & 25 deletions src/hooks/pages/dashboard/useNewInstanceStreamPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ import { useEntityCost } from '@/hooks/common/useEntityCost'
import { useRequestCRNs } from '@/hooks/common/useRequestEntity/useRequestCRNs'
import { useRequestCRNSpecs } from '@/hooks/common/useRequestEntity/useRequestCRNSpecs'
import { CRN, CRNSpecs, NodeLastVersions } from '@/domain/node'
import { Web3Provider } from '@ethersproject/providers'
import { defaultStreamDuration, StreamDurationField } from '@/hooks/form/useSelectStreamDuration'
import { superfluid } from 'aleph-sdk-ts/dist/accounts'
import { Chain } from 'aleph-sdk-ts/dist/messages/types'
import { ActionTypes } from '@/helpers/store'

Expand Down Expand Up @@ -131,35 +129,15 @@ export function useNewInstanceStreamPage(): UseNewInstanceStreamPage {
if (!node || !node.reward) throw new Error('Invalid node')
if (!state?.streamCost) throw new Error('Invalid stream cost')
if (window?.ethereum === undefined) throw new Error('No wallet found')

const web3Provider = new Web3Provider(window.ethereum)

const superfluidAccount = new superfluid.SuperfluidAccount(
web3Provider,
account.address,
)

await superfluidAccount.init()

const superTokenBalance = await superfluidAccount.getALEPHxBalance()
console.log('ALEPHx balance:', superTokenBalance.toString())

console.log('Target node:', node)
let flow = await superfluidAccount.getALEPHxFlow(node.reward)
console.log('Current flow:', flow.toString())

console.log('Setting flow to:', state.streamCost.toString())

await superfluidAccount.increaseALEPHxFlow(node.reward, state.streamCost)
flow = await superfluidAccount.getALEPHxFlow(node.reward)
console.log('New flow:', flow.toString())

const accountInstance = await manager.add({
...state,
payment: {
chain: Chain.AVAX,
type: PaymentMethod.Stream,
sender: account.address,
receiver: node.reward,
streamCost: state.streamCost,
streamDuration: state.streamDuration,
},
} as AddInstance)

Expand Down

0 comments on commit 45cb088

Please sign in to comment.