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

refactor(sdk): operatorContractUtils type safety #2919

Open
wants to merge 22 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
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
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ import { createClient, createTestStream } from '../../../utils'

const {
delegate,
deployOperatorContract,
deploySponsorshipContract,
generateWalletWithGasAndTokens,
deployTestOperatorContract,
deployTestSponsorshipContract,
createTestWallet,
stake
} = _operatorContractUtils

Expand Down Expand Up @@ -65,13 +65,13 @@ describe('MaintainTopologyService', () => {
})

it('happy path', async () => {
const operatorWallet = await generateWalletWithGasAndTokens()
const operatorWallet = await createTestWallet()
const [stream1, stream2] = await setUpStreams()
const sponsorship1 = await deploySponsorshipContract({ deployer: operatorWallet, streamId: stream1.id })
const sponsorship2 = await deploySponsorshipContract({ deployer: operatorWallet, streamId: stream2.id })
const operatorContract = await deployOperatorContract({ deployer: operatorWallet })
await delegate(operatorWallet, await operatorContract.getAddress(), 20000)
await stake(operatorContract, await sponsorship1.getAddress(), 10000)
const sponsorship1 = await deployTestSponsorshipContract({ deployer: operatorWallet, streamId: stream1.id })
const sponsorship2 = await deployTestSponsorshipContract({ deployer: operatorWallet, streamId: stream2.id })
const operatorContract = await deployTestOperatorContract({ deployer: operatorWallet })
await delegate(operatorWallet, await operatorContract.getAddress(), 20000n)
await stake(operatorContract, await sponsorship1.getAddress(), 10000n)

const createOperatorFleetState = OperatorFleetState.createOperatorFleetStateBuilder(
client,
Expand Down Expand Up @@ -104,7 +104,7 @@ describe('MaintainTopologyService', () => {
return containsAll(await getSubscribedStreamPartIds(client), await stream1.getStreamParts())
}, 10000, 1000)

await stake(operatorContract, await sponsorship2.getAddress(), 10000)
await stake(operatorContract, await sponsorship2.getAddress(), 10000n)
await until(async () => {
return containsAll(await getSubscribedStreamPartIds(client), [
...await stream1.getStreamParts(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@ import { createClient, createTestStream, formConfig, startBroker } from '../../.

const {
delegate,
deploySponsorshipContract,
generateWalletWithGasAndTokens,
setupOperatorContract,
deployTestSponsorshipContract,
createTestWallet,
setupTestOperatorContract,
sponsor,
stake
} = _operatorContractUtils

const DEFAULT_STREAM_PARTITION = 0
const SPONSOR_AMOUNT = 10000n

describe('OperatorPlugin', () => {

Expand All @@ -31,7 +32,7 @@ describe('OperatorPlugin', () => {
let operatorWallet: Wallet

beforeAll(async () => {
const deployment = (await setupOperatorContract({
const deployment = (await setupTestOperatorContract({
nodeCount: 1
}))
brokerWallet = deployment.nodeWallets[0]
Expand All @@ -54,11 +55,11 @@ describe('OperatorPlugin', () => {
const subscriber = createClient(await fetchPrivateKeyWithGas())
const stream = await createTestStream(subscriber, module)

const sponsorer = await generateWalletWithGasAndTokens()
const sponsorship1 = await deploySponsorshipContract({ streamId: stream.id, deployer: sponsorer })
await sponsor(sponsorer, await sponsorship1.getAddress(), 10000)
await delegate(operatorWallet, await operatorContract.getAddress(), 10000)
await stake(operatorContract, await sponsorship1.getAddress(), 10000)
const sponsorer = await createTestWallet()
const sponsorship1 = await deployTestSponsorshipContract({ streamId: stream.id, deployer: sponsorer })
await sponsor(sponsorer, await sponsorship1.getAddress(), SPONSOR_AMOUNT)
await delegate(operatorWallet, toEthereumAddress(await operatorContract.getAddress()), SPONSOR_AMOUNT)
await stake(operatorContract, await sponsorship1.getAddress(), SPONSOR_AMOUNT)

const publisher = createClient(fastPrivateKey())
await stream.grantPermissions({
Expand Down Expand Up @@ -112,11 +113,11 @@ describe('OperatorPlugin', () => {
const client = createClient(await fetchPrivateKeyWithGas())
const stream = await createTestStream(client, module)

const sponsorer = await generateWalletWithGasAndTokens()
const sponsorship = await deploySponsorshipContract({ streamId: stream.id, deployer: sponsorer })
await sponsor(sponsorer, await sponsorship.getAddress(), 10000)
await delegate(operatorWallet, await operatorContract.getAddress(), 10000)
await stake(operatorContract, await sponsorship.getAddress(), 10000)
const sponsorer = await createTestWallet()
const sponsorship = await deployTestSponsorshipContract({ streamId: stream.id, deployer: sponsorer })
await sponsor(sponsorer, await sponsorship.getAddress(), SPONSOR_AMOUNT)
await delegate(operatorWallet, toEthereumAddress(await operatorContract.getAddress()), SPONSOR_AMOUNT)
await stake(operatorContract, await sponsorship.getAddress(), SPONSOR_AMOUNT)

const operatorContractAddress = await operatorContract.getAddress()
broker = await startBroker({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ describe('announceNodeToContract', () => {
let operator: Operator

beforeEach(async () => {
const { operatorContract, nodeWallets } = await _operatorContractUtils.setupOperatorContract({
const { operatorContract, nodeWallets } = await _operatorContractUtils.setupTestOperatorContract({
nodeCount: 1
})
operator = createClient(nodeWallets[0].privateKey).getOperator(toEthereumAddress(await operatorContract.getAddress()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const TIMEOUT = 40 * 1000
describe('announceNodeToStream', () => {

it('publishes to stream', async () => {
const { operatorContract, nodeWallets } = await _operatorContractUtils.setupOperatorContract({
const { operatorContract, nodeWallets } = await _operatorContractUtils.setupTestOperatorContract({
nodeCount: 1
})
const operatorContractAddress = toEthereumAddress(await operatorContract.getAddress())
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import { Operator, StreamrConfig, streamrConfigABI } from '@streamr/network-contracts'
import {
SetupOperatorContractOpts,
SetupTestOperatorContractOpts,
_operatorContractUtils,
} from '@streamr/sdk'
import { Logger, toEthereumAddress, until } from '@streamr/utils'
import { Logger, StreamID, toEthereumAddress, until } from '@streamr/utils'
import { Contract } from 'ethers'
import { checkOperatorValueBreach } from '../../../../src/plugins/operator/checkOperatorValueBreach'
import { createClient, createTestStream } from '../../../utils'

const {
delegate,
deploySponsorshipContract,
generateWalletWithGasAndTokens,
getProvider,
setupOperatorContract,
deployTestSponsorshipContract,
createTestWallet,
getTestProvider,
setupTestOperatorContract,
sponsor,
stake
} = _operatorContractUtils
Expand All @@ -30,8 +30,8 @@ const getEarnings = async (operatorContract: Operator): Promise<bigint> => {

describe('checkOperatorValueBreach', () => {

let streamId: string
let deployConfig: SetupOperatorContractOpts
let streamId: StreamID
let deployConfig: SetupTestOperatorContractOpts

beforeAll(async () => {
const client = createClient(STREAM_CREATION_KEY)
Expand All @@ -46,19 +46,19 @@ describe('checkOperatorValueBreach', () => {

it('withdraws the other Operators earnings when they are above the limit', async () => {
// eslint-disable-next-line max-len
const { operatorContract: watcherOperatorContract, nodeWallets: watcherWallets } = await setupOperatorContract({ nodeCount: 1, ...deployConfig })
const { operatorWallet, operatorContract } = await setupOperatorContract(deployConfig)
const sponsorer = await generateWalletWithGasAndTokens()
await delegate(operatorWallet, await operatorContract.getAddress(), 20000)
const sponsorship1 = await deploySponsorshipContract({ earningsPerSecond: 100, streamId, deployer: operatorWallet })
await sponsor(sponsorer, await sponsorship1.getAddress(), 25000)
await stake(operatorContract, await sponsorship1.getAddress(), 10000)
const sponsorship2 = await deploySponsorshipContract({ earningsPerSecond: 200, streamId, deployer: operatorWallet })
await sponsor(sponsorer, await sponsorship2.getAddress(), 25000)
await stake(operatorContract, await sponsorship2.getAddress(), 10000)
const { operatorContract: watcherOperatorContract, nodeWallets: watcherWallets } = await setupTestOperatorContract({ nodeCount: 1, ...deployConfig })
const { operatorWallet, operatorContract } = await setupTestOperatorContract(deployConfig)
const sponsorer = await createTestWallet()
await delegate(operatorWallet, await operatorContract.getAddress(), 20000n)
const sponsorship1 = await deployTestSponsorshipContract({ earningsPerSecond: 100n, streamId, deployer: operatorWallet })
await sponsor(sponsorer, await sponsorship1.getAddress(), 25000n)
await stake(operatorContract, await sponsorship1.getAddress(), 10000n)
const sponsorship2 = await deployTestSponsorshipContract({ earningsPerSecond: 200n, streamId, deployer: operatorWallet })
await sponsor(sponsorer, await sponsorship2.getAddress(), 25000n)
await stake(operatorContract, await sponsorship2.getAddress(), 10000n)
const valueBeforeWithdraw = await operatorContract.valueWithoutEarnings()
const streamrConfigAddress = await operatorContract.streamrConfig()
const streamrConfig = new Contract(streamrConfigAddress, streamrConfigABI, getProvider()) as unknown as StreamrConfig
const streamrConfig = new Contract(streamrConfigAddress, streamrConfigABI, getTestProvider()) as unknown as StreamrConfig
const allowedDifference = valueBeforeWithdraw * (await streamrConfig.maxAllowedEarningsFraction()) / ONE_ETHER
const client = createClient(watcherWallets[0].privateKey)
const operator = client.getOperator(toEthereumAddress(await watcherOperatorContract.getAddress()))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,28 @@
import { _operatorContractUtils } from '@streamr/sdk'
import { fetchPrivateKeyWithGas } from '@streamr/test-utils'
import { Logger, toEthereumAddress, until } from '@streamr/utils'
import { Logger, StreamID, toEthereumAddress, until } from '@streamr/utils'
import { multiply } from '../../../../src/helpers/multiply'
import { maintainOperatorValue } from '../../../../src/plugins/operator/maintainOperatorValue'
import { createClient, createTestStream } from '../../../utils'

const {
delegate,
deploySponsorshipContract,
generateWalletWithGasAndTokens,
setupOperatorContract,
deployTestSponsorshipContract,
createTestWallet,
setupTestOperatorContract,
sponsor,
stake
} = _operatorContractUtils

const logger = new Logger(module)

const STAKE_AMOUNT = 10000
const SPONSOR_AMOUNT = 25000n
const STAKE_AMOUNT = 10000n
const SAFETY_FRACTION = 0.5 // 50%

describe('maintainOperatorValue', () => {

let streamId: string
let streamId: StreamID

beforeAll(async () => {
logger.debug('Creating stream for the test')
Expand All @@ -37,15 +38,15 @@ describe('maintainOperatorValue', () => {
* in network-contracts), and the configured safe limit in this test is 50%, i.e. 2.5 tokens.
*/
it('withdraws sponsorship earnings when earnings are above the safe threshold', async () => {
const { operatorWallet, operatorContract, nodeWallets } = await setupOperatorContract({
const { operatorWallet, operatorContract, nodeWallets } = await setupTestOperatorContract({
nodeCount: 1,
operatorConfig: {
operatorsCutPercent: 10
}
})
const sponsorer = await generateWalletWithGasAndTokens()
const sponsorship = await deploySponsorshipContract({ earningsPerSecond: 100, streamId, deployer: operatorWallet })
await sponsor(sponsorer, await sponsorship.getAddress(), 25000)
const sponsorer = await createTestWallet()
const sponsorship = await deployTestSponsorshipContract({ earningsPerSecond: 100n, streamId, deployer: operatorWallet })
await sponsor(sponsorer, await sponsorship.getAddress(), SPONSOR_AMOUNT)
await delegate(operatorWallet, await operatorContract.getAddress(), STAKE_AMOUNT)
await stake(operatorContract, await sponsorship.getAddress(), STAKE_AMOUNT)
const operator = createClient(nodeWallets[0].privateKey).getOperator(toEthereumAddress(await operatorContract.getAddress()))
Expand Down
41 changes: 21 additions & 20 deletions packages/node/test/smoke/inspect.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { config as CHAIN_CONFIG } from '@streamr/config'
import { StreamrConfig, streamrConfigABI } from '@streamr/network-contracts'
import { _operatorContractUtils } from '@streamr/sdk'
import { fetchPrivateKeyWithGas } from '@streamr/test-utils'
import { Logger, StreamID, TheGraphClient, wait, until } from '@streamr/utils'
import { Logger, StreamID, TheGraphClient, wait, until, toEthereumAddress, EthereumAddress } from '@streamr/utils'
import { Contract, formatEther, JsonRpcProvider, parseEther, Wallet } from 'ethers'
import fetch from 'node-fetch'
import { Broker, createBroker } from '../../src/broker'
Expand Down Expand Up @@ -37,10 +37,10 @@ import { OperatorPluginConfig } from './../../src/plugins/operator/OperatorPlugi
*/

const {
setupOperatorContract,
getProvider,
generateWalletWithGasAndTokens,
deploySponsorshipContract,
setupTestOperatorContract,
getTestProvider,
createTestWallet,
deployTestSponsorshipContract,
delegate,
stake,
getTestTokenContract,
Expand All @@ -62,18 +62,19 @@ const CLOSE_EXPIRED_FLAGS_MAX_AGE = 30 * 1000
const VALID_OPERATOR_COUNT = 3 // one flagger and at least two voters are needed (see VoteKickPolicy.sol:166)
const MAX_TEST_RUN_TIME = 15 * 60 * 1000

const DELEGATE_WEI = 50000
const STAKE_WEI = 10000
const REVIEWER_REWARD_WEI = 700
const FLAGGER_REWARD_WEI = 900
const DELEGATE_WEI = 50000n
const STAKE_WEI = 10000n
const REVIEWER_REWARD_WEI = 700n
const FLAGGER_REWARD_WEI = 900n
const SLASHING_FRACTION = 0.25
const SLASHING_WEI = BigInt(SLASHING_FRACTION * Number(STAKE_WEI))

// two operators and a sponsorship which have been created in dev-chain init
const PRE_BAKED_OPERATORS = [{
contractAddress: '0x8ac1cee54b9133ab7fe5418c826be60a6353d95e',
contractAddress: toEthereumAddress('0x8ac1cee54b9133ab7fe5418c826be60a6353d95e'),
privateKey: '0x4059de411f15511a85ce332e7a428f36492ab4e87c7830099dadbf130f1896ae'
}, {
contractAddress: '0xb63c856cf861a88f4fa8587716fdc4e69cdf9ef1',
contractAddress: toEthereumAddress('0xb63c856cf861a88f4fa8587716fdc4e69cdf9ef1'),
privateKey: '0x5e98cce00cff5dea6b454889f359a4ec06b9fa6b88e9d69b86de8e1c81887da0'
}]
const PRE_BAKED_SPONSORSHIP = '0x5fb705aeb6f9a84499c202fc02c33d6f249dc26a'
Expand All @@ -90,9 +91,9 @@ const createStream = async (): Promise<StreamID> => {
}

const createOperator = async (
pluginConfig: Partial<Omit<OperatorPluginConfig, 'operatorContractAddress'>>, sponsorshipAddress: string, isFreerider: boolean
pluginConfig: Partial<Omit<OperatorPluginConfig, 'operatorContractAddress'>>, sponsorshipAddress: EthereumAddress, isFreerider: boolean
): Promise<Operator> => {
const operator = await setupOperatorContract({
const operator = await setupTestOperatorContract({
nodeCount: 1,
operatorConfig: {
metadata: JSON.stringify({ redundancyFactor: 1 })
Expand Down Expand Up @@ -125,7 +126,7 @@ const createTheGraphClient = (): TheGraphClient => {
const configureBlockchain = async (): Promise<void> => {
const MINING_INTERVAL = 1100
logger.info('Configure blockchain')
const provider = getProvider() as JsonRpcProvider
const provider = getTestProvider() as JsonRpcProvider
await provider.send('evm_setAutomine', [true])
await createStream() // just some transaction
await provider.send('evm_setAutomine', [false])
Expand Down Expand Up @@ -220,8 +221,8 @@ describe('inspect', () => {
await streamrConfig.setSlashingFraction(parseEther(String(SLASHING_FRACTION)))
logger.info('Setup sponsorship')
const streamId = await createStream()
const sponsorer = await generateWalletWithGasAndTokens()
const sponsorship = await deploySponsorshipContract({ earningsPerSecond: 0, streamId, deployer: sponsorer })
const sponsorer = await createTestWallet()
const sponsorship = await deployTestSponsorshipContract({ earningsPerSecond: 0n, streamId, deployer: sponsorer })
logger.info('Create operators')
freeriderOperator = await createOperator({}, await sponsorship.getAddress(), true)
const CONFIG = {
Expand Down Expand Up @@ -251,7 +252,7 @@ describe('inspect', () => {
// select only offline nodes, but because of ETH-784 the reviewer set won't change).
logger.info('Unstake pre-baked operators')
for (const operator of PRE_BAKED_OPERATORS) {
const contract = getOperatorContract(operator.contractAddress).connect(new Wallet(operator.privateKey, getProvider())) as any
const contract = getOperatorContract(operator.contractAddress).connect(new Wallet(operator.privateKey, getTestProvider())) as any
await (await contract.unstake(PRE_BAKED_SPONSORSHIP)).wait()
}

Expand All @@ -271,7 +272,7 @@ describe('inspect', () => {
await operator.node.stop()
}
// revert to dev-chain default mining interval
await (getProvider() as JsonRpcProvider).send('evm_setIntervalMining', [DEV_CHAIN_DEFAULT_MINING_INTERVAL])
await (getTestProvider() as JsonRpcProvider).send('evm_setIntervalMining', [DEV_CHAIN_DEFAULT_MINING_INTERVAL])
})

/*
Expand Down Expand Up @@ -311,8 +312,8 @@ describe('inspect', () => {
}

// assert slashing and rewards
const token = getTestTokenContract().connect(getProvider())
expect(await getTokenBalance(freeriderOperator.contractAddress, token)).toEqual(DELEGATE_WEI - SLASHING_FRACTION * STAKE_WEI)
const token = getTestTokenContract().connect(getTestProvider())
expect(await getTokenBalance(freeriderOperator.contractAddress, token)).toEqual(DELEGATE_WEI - SLASHING_WEI)
expect(await getTokenBalance(flags[0].flagger, token)).toEqual(DELEGATE_WEI - STAKE_WEI + FLAGGER_REWARD_WEI)
for (const voter of flags[0].votes.map((vote) => vote.voter)) {
expect(await getTokenBalance(voter, token)).toEqual(DELEGATE_WEI - STAKE_WEI + REVIEWER_REWARD_WEI)
Expand Down
Loading
Loading