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

Preview4 node changes #2289

Closed
Closed
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
12 changes: 9 additions & 3 deletions packages/neo-one-client-common/src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,15 +221,21 @@ const TEN_THOUSAND_FIXED8 = fixed8FromDecimal(10000);
const ONE_HUNDRED_MILLION_FIXED8 = fixed8FromDecimal(100000000);

const nativeScriptHashes = {
GAS: '0x668e0c1f9d7b70a99dd9e06eadd4c784d641afbc',
NEO: '0xde5f57d430d3dece511cf975a8d37848cb9e0525',
Policy: '0xce06595079cd69583126dbfd1d2e25cca74cffe9',
Management: '0xcd97b70d82d69adfcd9165374109419fade8d6ab',
NEO: '0x0a46e2e37c9987f570b4af253fb77e7eef0f72b6',
GAS: '0xa6a6c15dcdc9b997dac448b6926522d22efeedfb',
Policy: '0xdde31084c0fdbebc7f5ed5f53a38905305ccee14',
Oracle: '0xb1c37d5847c2ae36bdde31d0cc833a7ad9667f8f',
Designation: '0xc0073f4c7069bf38995780c9da065f9b3949ea7a',
};

const nativeHashes = {
Management: hexToUInt160(nativeScriptHashes.Management),
GAS: hexToUInt160(nativeScriptHashes.GAS),
NEO: hexToUInt160(nativeScriptHashes.NEO),
Policy: hexToUInt160(nativeScriptHashes.Policy),
Oracle: hexToUInt160(nativeScriptHashes.Oracle),
Designation: hexToUInt160(nativeScriptHashes.Designation),
};

export const common = {
Expand Down
10 changes: 10 additions & 0 deletions packages/neo-one-client-common/src/crypto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,15 @@ const createPrivateKey = (): PrivateKey => common.bufferToPrivateKey(randomBytes

const toScriptHash = hash160;

const getContractHash = (sender: UInt160, script: Buffer) => {
const builder = new ScriptBuilder();
builder.emitOp('ABORT');
builder.emitPushUInt160(sender);
builder.emitPush(script);

return toScriptHash(builder.build());
};

// Takes various formats and converts to standard ECPoint
const toECPoint = (publicKey: Buffer): ECPoint => toECPointFromKeyPair(ec().keyFromPublic(publicKey));

Expand Down Expand Up @@ -891,6 +900,7 @@ export const crypto = {
verify,
privateKeyToPublicKey,
toScriptHash,
getContractHash,
toECPoint,
createKeyPair,
scriptHashToAddress,
Expand Down
7 changes: 6 additions & 1 deletion packages/neo-one-client-common/src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,12 @@ export const InvalidAttributeTypeJSONError = makeErrorWithCode(
);
export const InvalidAttributeTypeError = makeErrorWithCode(
'INVALID_ATTRIBUTE_TYPE',
(transactionAttributeType: number) => `Expected transaction type, found: ${transactionAttributeType.toString(16)}`,
(transactionAttributeType: number) =>
`Expected transaction attribute type, found: ${transactionAttributeType.toString(16)}`,
);
export const InvalidOracleResponseCodeError = makeErrorWithCode(
'INVALID_ORACLE_RESPONSE_CODE',
(value: number) => `Expected oracle response code, found: ${value.toString()}`,
);
export const InvalidAttributeUsageError = makeErrorWithCode(
'INVALID_ATTRIBUTE_USAGE',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,14 @@ export class TransactionModel<
this.networkFee = networkFee;
}

public getAttributes<T extends TAttribute>(isAttr: (attr: TAttribute) => attr is T): readonly T[] {
return this.attributes.filter(isAttr);
}

public getAttribute<T extends TAttribute>(isAttr: (attr: TAttribute) => attr is T): T | undefined {
return this.getAttributes(isAttr)[0];
}

public getScriptHashesForVerifying(): readonly UInt160[] {
return this.signers.map((signer) => signer.account);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { HighPriorityAttributeModel } from './HighPriorityAttributeModel';
import { OracleResponseModel } from './OracleResponseModel';

export type AttributeModel = HighPriorityAttributeModel;
export type AttributeModel = HighPriorityAttributeModel | OracleResponseModel;
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { InvalidAttributeTypeError, InvalidAttributeTypeJSONError } from '../../
import { AttributeTypeJSON } from '../../types';

export enum AttributeTypeModel {
HighPriority = 1,
HighPriority = 0x01,
OracleResponse = 0x11,
}

const isAttributeType = (value: number): value is AttributeTypeModel =>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { InvalidOracleResponseCodeError } from '../../../errors';

export enum OracleResponseCode {
Success = 0x00,

ConsensusUnreachable = 0x10,
NotFound = 0x12,
Timeout = 0x14,
Forbidden = 0x16,
ResponseTooLarge = 0x18,
InsufficientFunds = 0x1a,

Error = 0xff,
}

const isOracleResponseCode = (value: number): value is OracleResponseCode =>
// tslint:disable-next-line: strict-type-predicates
OracleResponseCode[value] !== undefined;

export const assertOracleResponseCode = (value: number): OracleResponseCode => {
if (isOracleResponseCode(value)) {
return value;
}

throw new InvalidOracleResponseCodeError(value);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { BN } from 'bn.js';
import { BinaryWriter } from '../../../BinaryWriter';
import { IOHelper } from '../../../IOHelper';
import { AttributeBaseModel } from './AttributeBaseModel';
import { AttributeTypeModel } from './AttributeTypeModel';
import { OracleResponseCode } from './OracleResponseCode';

export interface OracleResponseModelAdd {
readonly id: BN;
readonly code: OracleResponseCode;
readonly result: Buffer;
}

export class OracleResponseModel extends AttributeBaseModel {
public readonly type = AttributeTypeModel.OracleResponse;
public readonly allowMultiple = false;
public readonly id: BN;
public readonly code: OracleResponseCode;
public readonly result: Buffer;

public constructor({ id, code, result }: OracleResponseModelAdd) {
super();
this.id = id;
this.code = code;
this.result = result;
}

protected serializeWithoutTypeBase(writer: BinaryWriter) {
writer.writeUInt64LE(this.id);
writer.writeUInt8(this.code);
writer.writeVarBytesLE(this.result);
}

protected sizeExclusive(): number {
return IOHelper.sizeOfUInt64LE + IOHelper.sizeOfUInt8 + IOHelper.sizeOfVarBytesLE(this.result);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ export * from './AttributeBaseModel';
export * from './AttributeModel';
export * from './AttributeTypeModel';
export * from './HighPriorityAttributeModel';
export * from './OracleResponseCode';
export * from './OracleResponseModel';
18 changes: 16 additions & 2 deletions packages/neo-one-client-common/src/models/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { UInt256Hex } from '../common';
import { UserAccount } from '../types';
import { ContractParameterTypeModel } from './ContractParameterTypeModel';
import { StorageFlagsModel } from './StorageFlagsModel';
import { AttributeTypeModel } from './transaction/attribute/AttributeTypeModel';
import { AttributeTypeModel } from './transaction';
import { TriggerType, TriggerTypeJSON } from './trigger';
import { VerifyResultModel } from './VerifyResultModel';
import { VMState, VMStateJSON } from './vm';
Expand Down Expand Up @@ -196,10 +196,23 @@ export interface SignerJSON {
readonly allowedgroups?: readonly string[];
}

export interface AttributeJSON {
export interface AttributeJSONBase {
readonly type: AttributeTypeJSON;
}

export interface HighPriorityAttributeJSON extends AttributeJSONBase {
readonly type: 'HighPriority';
}

export interface OracleResponseJSON extends AttributeJSONBase {
readonly type: 'OracleResponse';
readonly id: string;
readonly code: number;
readonly result: string;
}

export type AttributeJSON = HighPriorityAttributeJSON | OracleResponseJSON;

export type AttributeTypeJSON = keyof typeof AttributeTypeModel;

export type VerifyResultJSON = keyof typeof VerifyResultModel;
Expand Down Expand Up @@ -389,6 +402,7 @@ export interface ContractParameterDefinitionJSON {

export interface ContractJSON {
readonly id: number;
readonly updatecounter: number;
readonly hash: string;
readonly script: string;
readonly manifest: ContractManifestJSON;
Expand Down
14 changes: 14 additions & 0 deletions packages/neo-one-client-common/src/prices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,3 +199,17 @@ export const getOpCodePrice = (value: Op): BigNumber => {

return fee;
};

export const signatureContractCost = getOpCodePrice(Op.PUSHDATA1)
.multipliedBy(2)
.plus(getOpCodePrice(Op.PUSHNULL))
.plus(getOpCodePrice(Op.SYSCALL))
.plus(ECDsaVerifyPrice);

export const multiSignatureContractCost = (m: number, n: number) =>
getOpCodePrice(Op.PUSHDATA1)
.multipliedBy(m + n)
.plus(getOpCodePrice(Op.PUSHINT8).multipliedBy(2))
.plus(getOpCodePrice(Op.PUSHNULL))
.plus(getOpCodePrice(Op.SYSCALL))
.plus(ECDsaVerifyPrice.multipliedBy(n));
20 changes: 16 additions & 4 deletions packages/neo-one-client-common/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
AccountContract,
AttributeTypeModel,
NotificationJSON,
OracleResponseCode,
StackItemJSON,
TriggerTypeJSON,
VerifyResultModel,
Expand Down Expand Up @@ -73,21 +74,28 @@ export type NetworkType = 'main' | 'test' | string;
* @see Attribute
*/
export interface AttributeBase {
/**
* `type` specifies the `Attribute` type
*/
readonly type: AttributeTypeModel;
}
/**
* `Attribute` whose transaction is "high priority".
*/
export interface HighPriorityAttribute extends AttributeBase {
/**
* `type` specifies the `Attribute` type
*/
readonly type: AttributeTypeModel.HighPriority;
}

export interface OracleResponse extends AttributeBase {
readonly type: AttributeTypeModel.OracleResponse;
readonly id: BigNumber;
readonly code: OracleResponseCode;
readonly result: BufferString;
}
/**
* `Attribute`s are used to store additional data on `Transaction`s.
*/
export type Attribute = HighPriorityAttribute;
export type Attribute = HighPriorityAttribute | OracleResponse;

export type WitnessScope =
| 'None'
Expand Down Expand Up @@ -429,6 +437,10 @@ export interface Transfer {
* Destination address.
*/
readonly to: AddressString;
/**
* Additional data to be attached to the transaction. Typed as `any` but should be used cautiously since it will need to be converted.
*/
readonly data?: any;
}

/**
Expand Down
4 changes: 4 additions & 0 deletions packages/neo-one-client-core/src/provider/JSONRPCClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ export class JSONRPCClient {
return this.withInstance(async (provider) => provider.request({ method: 'getfeeperbyte' }));
}

public async getExecFeeFactor(): Promise<number> {
return this.withInstance(async (provider) => provider.request({ method: 'getexecfeefactor' }));
}

public async getContract(address: AddressString): Promise<ContractJSON> {
return this.withInstance(async (provider) =>
provider.request({
Expand Down
35 changes: 30 additions & 5 deletions packages/neo-one-client-core/src/provider/NEOONEDataProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
ApplicationLogJSON,
Attribute,
AttributeJSON,
AttributeTypeModel,
Block,
BlockJSON,
ConfirmedTransaction,
Expand All @@ -27,14 +28,14 @@ import {
ContractPermission,
ContractPermissionJSON,
DeveloperProvider,
FeelessTransactionModel,
GetOptions,
Hash256String,
IterOptions,
JSONHelper,
NetworkSettings,
NetworkSettingsJSON,
NetworkType,
OracleResponseJSON,
Peer,
PrivateNetworkSettings,
RawApplicationLogData,
Expand All @@ -54,9 +55,9 @@ import {
TransactionModel,
TransactionReceipt,
TransactionReceiptJSON,
UInt160Hex,
VerifyResultJSON,
VerifyResultModel,
UInt160Hex,
} from '@neo-one/client-common';
import { utils as commonUtils } from '@neo-one/utils';
import { AsyncIterableX } from '@reactivex/ix-es2015-cjs/asynciterable/asynciterablex';
Expand Down Expand Up @@ -150,6 +151,10 @@ export class NEOONEDataProvider implements DeveloperProvider {
return new BigNumber(feePerByte);
}

public async getExecFeeFactor(): Promise<number> {
return this.mutableClient.getExecFeeFactor();
}

public async getVerificationCost(
hash: AddressString,
transaction: TransactionModel,
Expand Down Expand Up @@ -356,9 +361,29 @@ export class NEOONEDataProvider implements DeveloperProvider {
}

private convertAttributes(attributes: readonly AttributeJSON[]): readonly Attribute[] {
return attributes.map((attribute) => ({
type: toAttributeType(attribute.type),
}));
return attributes.map(this.convertAttribute);
}

private convertAttribute(attribute: AttributeJSON): Attribute {
const type = toAttributeType(attribute.type);
switch (type) {
case AttributeTypeModel.HighPriority:
return {
type,
};
case AttributeTypeModel.OracleResponse:
// tslint:disable-next-line: no-any we know this is true but TS is being mean
const oracleJSON = attribute as OracleResponseJSON;

return {
type,
id: new BigNumber(oracleJSON.id),
code: oracleJSON.code,
result: oracleJSON.result,
};
default:
throw new Error();
}
}

private convertContract(contract: ContractJSON): Contract {
Expand Down
5 changes: 4 additions & 1 deletion packages/neo-one-client-core/src/provider/NEOONEProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import {
Account,
AddressString,
Block,
FeelessTransactionModel,
GetOptions,
Hash256String,
IterOptions,
Expand Down Expand Up @@ -85,6 +84,10 @@ export class NEOONEProvider implements Provider {
return this.getProvider(network).getFeePerByte();
}

public async getExecFeeFactor(network: NetworkType): Promise<number> {
return this.getProvider(network).getExecFeeFactor();
}

public async getVerificationCost(
network: NetworkType,
hash: UInt160Hex,
Expand Down
Loading