Skip to content

Commit

Permalink
feat(test): fixup 'createNode' in @neo-one/smart-contract-test (#2266)
Browse files Browse the repository at this point in the history
  • Loading branch information
danwbyrne authored Dec 28, 2020
1 parent 762dc1b commit 5215156
Show file tree
Hide file tree
Showing 40 changed files with 1,028 additions and 747 deletions.
6 changes: 6 additions & 0 deletions packages/neo-one-build-tools/types/unit.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
declare interface One {
readonly addCleanup: (callback: () => Promise<void> | void) => void;
readonly cleanupTest: () => Promise<void>;
readonly teardown: () => Promise<void>;
}
declare const one: One;
1 change: 1 addition & 0 deletions packages/neo-one-client-common/src/models/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,7 @@ export interface TrimmedBlockJSON extends BlockBaseJSON {
}

export interface NetworkSettingsJSON {
readonly blockcount: number;
readonly decrementinterval: number;
readonly generationamount: readonly number[];
readonly privatekeyversion: number;
Expand Down
1 change: 1 addition & 0 deletions packages/neo-one-client-common/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2437,6 +2437,7 @@ export type ParamJSON =
* Constant settings used to initialize the client APIs.
*/
export interface NetworkSettings {
readonly blockCount: number;
readonly decrementInterval: number;
readonly generationAmount: readonly number[];
readonly privateKeyVersion: number;
Expand Down
4 changes: 2 additions & 2 deletions packages/neo-one-client-core/src/Client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -645,12 +645,12 @@ export class Client<
): Promise<RawCallReceipt> {
try {
args.assertString('network', network);
args.assertAddress('contract', contract);
const contractHash = args.tryGetUInt160Hex('contract', contract);
args.assertString('method', method);
args
.assertArray('params', params)
.forEach((param) => args.assertNullableScriptBuilderParam('params.param', param));
const receipt = await this.getNetworkProvider(network).call(network, contract, method, params);
const receipt = await this.getNetworkProvider(network).call(network, contractHash, method, params);
await this.hooks.afterCall.promise(receipt);

return receipt;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { common, crypto, ScriptBuilder } from '@neo-one/client-common';
import { common, crypto } from '@neo-one/client-common';
import { constants } from '@neo-one/utils';
import BigNumber from 'bignumber.js';
import { NEOONEProvider, NEOONEDataProvider } from '../../provider';
import { NEOONEProvider } from '../../provider';
import { LocalKeyStore, LocalMemoryStore, LocalUserAccountProvider } from '../../user';

const secondaryKeyString = '04c1784140445016cf0f8cc86dd10ad8764e1a89c563c500e21ac19a5d905ab3';
Expand Down Expand Up @@ -138,25 +138,71 @@ describe.skip('Test LocalUserAccountProvider transfer methods -- staging network

expect(stackReturn.value).toEqual(true);
});

test('Claim Gas -- forming our own transaction', async () => {
const keystore = new LocalKeyStore(new LocalMemoryStore());
const account = await keystore.addUserAccount(masterAccount);

const provider = new NEOONEProvider([providerOptions]);
const localProvider = new LocalUserAccountProvider({ provider, keystore });

const unclaimedInit = await provider.getUnclaimed('test', account.userAccount.id.address);

const transfer = {
amount: new BigNumber(0),
asset: common.nativeScriptHashes.NEO,
to: account.userAccount.id.address,
};

const result = await localProvider.transfer([transfer], {
maxNetworkFee: new BigNumber(-1),
maxSystemFee: new BigNumber(-1),
});

await result.confirmed();

const unclaimedPost = await provider.getUnclaimed('test', account.userAccount.id.address);
expect(unclaimedPost.toNumber()).toBeLessThan(unclaimedInit.toNumber());
});

test('Claim Gas -- using LUAP method', async () => {
const keystore = new LocalKeyStore(new LocalMemoryStore());
const account = await keystore.addUserAccount(masterAccount);

const provider = new NEOONEProvider([providerOptions]);
const localProvider = new LocalUserAccountProvider({ provider, keystore });

const unclaimedInit = await provider.getUnclaimed('test', account.userAccount.id.address);

const result = await localProvider.claim({
from: account.userAccount.id,
maxNetworkFee: new BigNumber(-1),
maxSystemFee: new BigNumber(-1),
});

await result.confirmed();

const unclaimedPost = await provider.getUnclaimed('test', account.userAccount.id.address);
expect(unclaimedPost.toNumber()).toBeLessThan(unclaimedInit.toNumber());
});
});

describe('contract info / usage testing', () => {
describe.skip('contract info / usage testing', () => {
const knownContractHashString = '0x79597a92440ce385fe1b0f4d9d2a92ca8608a575';
const knownContractHash = common.stringToUInt160(knownContractHashString);

const providerOptions = {
network: 'test',
rpcURL: 'http://localhost:8081/rpc',
rpcURL: 'https://staging.neotracker.io/rpc',
};
const provider = new NEOONEProvider([providerOptions]);

test('use `call` to get name of NEO contract', async () => {
const result = await provider.call('test', common.nativeScriptHashes.NEO, 'name', []);
test('use `call` to get name of a non-native contract', async () => {
const result = await provider.call('test', knownContractHashString, 'name', []);
const value = result.stack[0];
if (typeof value === 'string') {
throw new Error(value);
}

expect(value.value).toEqual('NEO');
expect(value.value).toEqual('S3 Plus');
});
});
27 changes: 21 additions & 6 deletions packages/neo-one-client-core/src/args.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,22 @@ export const assertAddress = (name: string, addressIn?: unknown): AddressString
}
};

export const tryGetUInt160Hex = (name: string, addressOrUInt160In: unknown): UInt160Hex => {
const addressOrUInt160 = assertString(name, addressOrUInt160In);

try {
scriptHashToAddress(addressOrUInt160);

return addressOrUInt160;
} catch {
try {
return addressToScriptHash(addressOrUInt160);
} catch {
throw new InvalidArgumentError('AddressOrUInt160', name, addressOrUInt160);
}
}
};

export const assertHash256 = (name: string, hash?: unknown): Hash256String => {
const value = assertString(name, hash);

Expand Down Expand Up @@ -798,7 +814,6 @@ export const assertContractManifest = (name: string, value?: unknown): ContractM
}

return {
hash: assertProperty(value, 'ContractManifest', 'hash', assertUInt160Hex),
groups: assertProperty(value, 'ContractManifest', 'groups', assertArray).map((group) =>
assertContractGroup('ContractManifest.groups', group),
),
Expand Down Expand Up @@ -950,7 +965,7 @@ export const assertTransfer = (name: string, value?: unknown): Transfer => {

return {
amount: assertProperty(value, 'Transfer', 'amount', assertBigNumber),
asset: assertProperty(value, 'Transfer', 'asset', assertAddress),
asset: assertProperty(value, 'Transfer', 'asset', tryGetUInt160Hex),
to: assertProperty(value, 'Transfer', 'to', assertAddress),
};
};
Expand Down Expand Up @@ -1009,8 +1024,8 @@ export const assertTransactionOptions = (name: string, options?: unknown): Trans
attributes: assertProperty(options, 'TransactionOptions', 'attributes', assertNullableArray).map((value) =>
assertAttribute('TransactionOption.attributes', value),
),
networkFee: assertProperty(options, 'TransactionOptions', 'networkFee', assertNullableBigNumber),
systemFee: assertProperty(options, 'TransactionOptions', 'systemFee', assertNullableBigNumber),
maxNetworkFee: assertProperty(options, 'TransactionOptions', 'networkFee', assertNullableBigNumber),
maxSystemFee: assertProperty(options, 'TransactionOptions', 'systemFee', assertNullableBigNumber),
};
};

Expand All @@ -1034,13 +1049,13 @@ export const assertInvokeSendUnsafeReceiveTransactionOptions = (
'attributes',
assertNullableArray,
).map((value) => assertAttribute('TransactionOption.attributes', value)),
networkFee: assertProperty(
maxNetworkFee: assertProperty(
options,
'InvokeSendUnsafeReceiveTransactionOptions',
'networkFee',
assertNullableBigNumber,
),
systemFee: assertProperty(
maxSystemFee: assertProperty(
options,
'InvokeSendUnsafeReceiveTransactionOptions',
'systemFee',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,7 @@ export class NEOONEDataProvider implements DeveloperProvider {

private convertNetworkSettings(settings: NetworkSettingsJSON): NetworkSettings {
return {
blockCount: settings.blockcount,
decrementInterval: settings.decrementinterval,
generationAmount: settings.generationamount,
privateKeyVersion: settings.privatekeyversion,
Expand Down
5 changes: 3 additions & 2 deletions packages/neo-one-client-core/src/provider/NEOONEProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
Transaction,
TransactionModel,
TransactionReceipt,
UInt160Hex,
} from '@neo-one/client-common';
import BigNumber from 'bignumber.js';
import { BehaviorSubject, Observable } from 'rxjs';
Expand Down Expand Up @@ -86,7 +87,7 @@ export class NEOONEProvider implements Provider {

public async getVerificationCost(
network: NetworkType,
hash: AddressString,
hash: UInt160Hex,
transaction: TransactionModel,
): Promise<{
readonly fee: BigNumber;
Expand All @@ -101,7 +102,7 @@ export class NEOONEProvider implements Provider {

public async call(
network: NetworkType,
contract: AddressString,
contract: UInt160Hex,
method: string,
params: ReadonlyArray<ScriptBuilderParam | undefined>,
): Promise<RawCallReceipt> {
Expand Down
47 changes: 11 additions & 36 deletions packages/neo-one-client-core/src/user/LocalUserAccountProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -403,10 +403,7 @@ export class LocalUserAccountProvider<TKeyStore extends KeyStore = KeyStore, TPr
throw new Error('temporary');
}

const [{ addressVersion }, { count, messageMagic }] = await Promise.all([
this.provider.getNetworkSettings(from.network),
this.getCountAndMagic(from.network),
]);
const { addressVersion, blockCount, messageMagic } = await this.provider.getNetworkSettings(from.network);

transfers.forEach((transfer) => {
sb.emitAppCall(
Expand All @@ -426,7 +423,7 @@ export class LocalUserAccountProvider<TKeyStore extends KeyStore = KeyStore, TPr
});

const nonce = utils.randomUShort();
const validUntilBlock = count + validBlockCount;
const validUntilBlock = blockCount + validBlockCount;

const feelessTransaction = new TransactionModel({
version: 0,
Expand Down Expand Up @@ -475,39 +472,17 @@ export class LocalUserAccountProvider<TKeyStore extends KeyStore = KeyStore, TPr
protected async executeClaim(
from: UserAccountID,
attributes: readonly Attribute[],
networkFee: BigNumber,
maxNetworkFee: BigNumber,
maxSystemFee: BigNumber,
validBlockCount: number,
): Promise<TransactionResult> {
const toAccount = this.getUserAccount(from);
const unclaimedAmount = await this.provider.getUnclaimed(from.network, from.address);
const toHash = crypto.toScriptHash(crypto.createSignatureRedeemScript(common.stringToECPoint(toAccount.publicKey)));
const script = new ScriptBuilder()
.emitAppCall(common.nativeHashes.GAS, 'transfer', [
addressToScriptHash(from.address),
common.nativeHashes.GAS,
unclaimedAmount.toString(),
])
.build();

const [{ gas }, { count, messageMagic }] = await Promise.all([
this.getSystemFee({ from, attributes, script }),
this.getCountAndMagic(from),
]);
const transfer: Transfer = {
to: from.address,
asset: common.nativeScriptHashes.NEO,
amount: new BigNumber(0),
};

const transaction = new TransactionModel({
systemFee: utils.bigNumberToBN(gas, 8), // TODO: check this. check decimals
networkFee: utils.bigNumberToBN(networkFee, 8), // TODO: check decimals
script,
attributes: this.convertAttributes(attributes),
messageMagic,
validUntilBlock: count + 240,
});

return this.sendTransaction<Transaction>({
from,
transaction,
onConfirm: async ({ receipt }) => receipt,
networkFee,
});
return this.executeTransfer([transfer], from, attributes, maxNetworkFee, maxSystemFee, validBlockCount);
}

// TODO: see invokeScript and invokeFunction in neo-modules
Expand Down
27 changes: 7 additions & 20 deletions packages/neo-one-client-core/src/user/UserAccountProviderBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
AttributeModel,
Block,
common,
FeelessTransactionModel,
ForwardValue,
GetOptions,
Hash256String,
Expand All @@ -21,25 +20,22 @@ import {
RawInvocationData,
RawInvokeReceipt,
ScriptBuilderParam,
Signer,
SignerModel,
SourceMaps,
Transaction,
TransactionModel,
TransactionOptions,
TransactionReceipt,
TransactionResult,
Transfer,
UInt160,
UserAccount,
UserAccountID,
utils,
Witness,
WitnessModel,
UInt160Hex,
} from '@neo-one/client-common';
import { Labels, utils as commonUtils } from '@neo-one/utils';
import BigNumber from 'bignumber.js';
import { BN } from 'bn.js';
import debug from 'debug';
import { Observable } from 'rxjs';
import { clientUtils } from '../clientUtils';
Expand Down Expand Up @@ -124,7 +120,7 @@ export interface Provider {
readonly testTransaction: (network: NetworkType, transaction: TransactionModel) => Promise<RawCallReceipt>;
readonly call: (
network: NetworkType,
contract: AddressString,
contract: UInt160Hex,
method: string,
params: ReadonlyArray<ScriptBuilderParam | undefined>,
) => Promise<RawCallReceipt>;
Expand All @@ -136,7 +132,7 @@ export interface Provider {
readonly getAccount: (network: NetworkType, address: AddressString) => Promise<Account>;
readonly getVerificationCost: (
network: NetworkType,
hash: AddressString,
hash: UInt160Hex,
transaction: TransactionModel,
) => Promise<{
readonly fee: BigNumber;
Expand Down Expand Up @@ -208,7 +204,7 @@ export abstract class UserAccountProviderBase<TProvider extends Provider> {
public async claim(options?: TransactionOptions): Promise<TransactionResult> {
const { from, attributes, maxNetworkFee, maxSystemFee, validBlockCount } = this.getTransactionOptions(options);

return this.capture(async () => this.executeClaim(from, attributes, networkFee), {
return this.capture(async () => this.executeClaim(from, attributes, maxNetworkFee, maxSystemFee, validBlockCount), {
name: 'neo_claim',
});
}
Expand Down Expand Up @@ -658,7 +654,9 @@ export abstract class UserAccountProviderBase<TProvider extends Provider> {
protected abstract async executeClaim(
from: UserAccountID,
attributes: readonly Attribute[],
networkFee: BigNumber,
maxNetworkFee: BigNumber,
maxSystemFee: BigNumber,
validBlockCount: number,
): Promise<TransactionResult>;

protected async invokeRaw<T extends TransactionReceipt>({
Expand Down Expand Up @@ -725,17 +723,6 @@ export abstract class UserAccountProviderBase<TProvider extends Provider> {
);
}

protected async getCountAndMagic(
network: NetworkType,
): Promise<{ readonly count: number; readonly messageMagic: number }> {
const [count, { messageMagic }] = await Promise.all([
this.provider.getBlockCount(network),
this.provider.getNetworkSettings(network),
]);

return { count, messageMagic };
}

private getScriptAndInvokeMethodOptions(
invokeMethodOptionsOrScript: InvokeMethodOptions | Buffer,
): { readonly script: Buffer; readonly invokeMethodOptions: InvokeMethodOptions | undefined } {
Expand Down
Loading

0 comments on commit 5215156

Please sign in to comment.