Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

Commit

Permalink
Merge pull request #972 from EOSIO/feature_adjustments
Browse files Browse the repository at this point in the history
Feature adjustments to resource payer and read only
  • Loading branch information
Brad Hart authored Jul 6, 2021
2 parents 9dafdfa + fb85962 commit 9c8d70d
Show file tree
Hide file tree
Showing 10 changed files with 201 additions and 167 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
.DS_Store
.idea
.vscode
dist/
dist-web/
node_modules/
Expand Down
2 changes: 1 addition & 1 deletion docs/how-to-guides/20_how-to-set-a-payer.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
After the release of v2.2 of nodeos, the transaction sponsorship feature is available to sponsor the resources for a transaction. To set a separate payer for the resources for a transaction, add a `resource_payer` object to your transaction that specifies the `payer`, `max_net_bytes`, `max_cpu_us`, and `max_memory_bytes`. This functionality requires the `RESOURCE_PAYER` feature to be enabled on the chain.
After the release of v2.2 of nodeos, the resource payer feature is available to sponsor the resources for a transaction. To set a separate payer for the resources for a transaction, add a `resource_payer` object to your transaction that specifies the `payer`, `max_net_bytes`, `max_cpu_us`, and `max_memory_bytes`. This functionality requires the `RESOURCE_PAYER` protocol feature to be enabled on the chain.

A typical use-case for this feature has a service or application pay for the resources of a transaction instead of their users. Since authorization is required for both the user in the transaction and the payer, a possible workflow would have the transaction signed by the user's wallet application and then also signed by the service/application before sent to nodeos.

Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,15 @@
"crypto-browserify": "^3.12.0",
"cypress": "^7.6.0",
"eosjs-ecc": "^4.0.7",
"eslint": "^7.29.0",
"eslint": "^7.30.0",
"jest": "^26.6.3",
"jest-extended": "^0.11.5",
"jest-fetch-mock": "^3.0.3",
"rimraf": "^3.0.2",
"ts-jest": "^26.5.6",
"ts-loader": "^9.2.3",
"typescript": "^4.3.5",
"webpack": "^5.41.1",
"webpack": "^5.42.1",
"webpack-cli": "^4.7.2"
},
"jest": {
Expand Down
6 changes: 3 additions & 3 deletions src/eosjs-api-interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ export interface SignatureProvider {

export interface ResourcePayer {
payer: string;
max_net_bytes: number|string;
max_cpu_us: number|string;
max_memory_bytes: number|string;
max_net_bytes: number;
max_cpu_us: number;
max_memory_bytes: number;
}

export interface Transaction {
Expand Down
46 changes: 36 additions & 10 deletions src/eosjs-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,9 @@ export class Api {
extensionBuffer.pushArray(ser.hexToUint8Array(extensionData[1]));
const deserializedObj = types.get(transactionExtension.type).deserialize(extensionBuffer);
if (extensionData[0] === 1) {
deserializedObj.max_net_bytes = Number(deserializedObj.max_net_bytes);
deserializedObj.max_cpu_us = Number(deserializedObj.max_cpu_us);
deserializedObj.max_memory_bytes = Number(deserializedObj.max_memory_bytes);
transaction.resource_payer = deserializedObj;
}
});
Expand Down Expand Up @@ -390,14 +393,18 @@ export class Api {
});
}
if (broadcast) {
let result;
if (readOnlyTrx) {
return this.rpc.push_ro_transaction(pushTransactionArgs, returnFailureTraces) as Promise<ReadOnlyTransactResult>;
}
if (compression) {
return this.pushCompressedSignedTransaction(pushTransactionArgs) as Promise<TransactResult>;
return this.pushCompressedSignedTransaction(
pushTransactionArgs,
readOnlyTrx,
returnFailureTraces,
) as Promise<TransactResult|ReadOnlyTransactResult>;
}
return this.pushSignedTransaction(pushTransactionArgs) as Promise<TransactResult>;
return this.pushSignedTransaction(
pushTransactionArgs,
readOnlyTrx,
returnFailureTraces,
) as Promise<TransactResult|ReadOnlyTransactResult>;
}
return pushTransactionArgs as PushTransactionArgs;
}
Expand Down Expand Up @@ -462,8 +469,17 @@ export class Api {

/** Broadcast a signed transaction */
public async pushSignedTransaction(
{ signatures, serializedTransaction, serializedContextFreeData }: PushTransactionArgs
): Promise<TransactResult> {
{ signatures, serializedTransaction, serializedContextFreeData }: PushTransactionArgs,
readOnlyTrx = false,
returnFailureTraces = false,
): Promise<TransactResult|ReadOnlyTransactResult> {
if (readOnlyTrx) {
return this.rpc.push_ro_transaction({
signatures,
serializedTransaction,
serializedContextFreeData,
}, returnFailureTraces);
}
return this.rpc.push_transaction({
signatures,
serializedTransaction,
Expand All @@ -472,12 +488,22 @@ export class Api {
}

public async pushCompressedSignedTransaction(
{ signatures, serializedTransaction, serializedContextFreeData }: PushTransactionArgs
): Promise<TransactResult> {
{ signatures, serializedTransaction, serializedContextFreeData }: PushTransactionArgs,
readOnlyTrx = false,
returnFailureTraces = false,
): Promise<TransactResult|ReadOnlyTransactResult> {
const compressedSerializedTransaction = this.deflateSerializedArray(serializedTransaction);
const compressedSerializedContextFreeData =
this.deflateSerializedArray(serializedContextFreeData || new Uint8Array(0));

if (readOnlyTrx) {
return this.rpc.push_ro_transaction({
signatures,
compression: 1,
serializedTransaction: compressedSerializedTransaction,
serializedContextFreeData: compressedSerializedContextFreeData
}, returnFailureTraces);
}
return this.rpc.push_transaction({
signatures,
compression: 1,
Expand Down
12 changes: 6 additions & 6 deletions src/tests/eosjs-api.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -329,18 +329,18 @@ describe('eosjs-api', () => {
context_free_actions: [] as any,
resource_payer: {
payer: 'payer',
max_net_bytes: '4096',
max_cpu_us: '250',
max_memory_bytes: '0'
max_net_bytes: 4096,
max_cpu_us: 250,
max_memory_bytes: 0
}
};
const serialized = [[1, '0000000080ABBCA90010000000000000FA000000000000000000000000000000']];
const deserialized = {
resource_payer: {
payer: 'payer',
max_net_bytes: '4096',
max_cpu_us: '250',
max_memory_bytes: '0'
max_net_bytes: 4096,
max_cpu_us: 250,
max_memory_bytes: 0
}
};

Expand Down
14 changes: 6 additions & 8 deletions src/tests/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -222,25 +222,23 @@ const readOnlyQuery = async () => {
}, {
blocksBehind: 3,
expireSeconds: 30,
compression: true,
readOnlyTrx: true,
returnFailureTraces: true,
});
};

const readOnlyFailureTrace = async () => {
return await api.transact({
actions: [{
account: 'eosio.token',
name: 'transfer',
account: 'eosio',
name: 'setpriv',
authorization: [{
actor: 'alice',
actor: 'bob',
permission: 'active',
}],
data: {
from: 'alice',
to: 'bob',
quantity: '2000000.0000 SYS',
memo: 'failureTrace',
account: 'bob',
is_priv: '1'
},
}]
}, {
Expand Down
6 changes: 2 additions & 4 deletions src/tests/node.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,14 +122,12 @@ describe('Node JS environment', () => {
});

it('returns failure trace for failed transaction', async () => {
let err;
try {
await tests.readOnlyFailureTrace();
} catch (e) {
err = e.details;
expect(e.details.code).toEqual(3090004);
expect(e.details.stack[0].format).toEqual('missing authority of ${account}');
}
expect(err.code).toEqual(3050003);
expect(err.stack[0].data.s).toEqual('overdrawn balance');
});

it('throws appropriate error message without configuration object or TAPOS in place', async () => {
Expand Down
30 changes: 14 additions & 16 deletions src/tests/web.html
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,7 @@
}, {
blocksBehind: 3,
expireSeconds: 30,
compression: true,
readOnlyTrx: true,
});
}
Expand Down Expand Up @@ -583,20 +584,18 @@

const readOnlyFailureTrace = async () => {
return await api.transact({
actions: [{
account: 'eosio.token',
name: 'transfer',
authorization: [{
actor: 'alice',
permission: 'active',
}],
data: {
from: 'alice',
to: 'bob',
quantity: '2000000.0000 SYS',
memo: 'failureTrace',
},
}]
actions: [{
account: 'eosio',
name: 'setpriv',
authorization: [{
actor: 'bob',
permission: 'active',
}],
data: {
account: 'bob',
is_priv: '1'
},
}]
}, {
blocksBehind: 3,
expireSeconds: 30,
Expand All @@ -613,8 +612,7 @@
try {
await readOnlyFailureTrace();
} catch (err) {
console.log(err);
if (err.details.code === 3050003 && err.details.stack[0].data.s === 'overdrawn balance') {
if (err.details.code === 3090004 && err.details.stack[0].format === 'missing authority of ${account}') {
resultsLabel.className = "success";
resultsLabel.innerText = SUCCESS;
return true;
Expand Down
Loading

0 comments on commit 9c8d70d

Please sign in to comment.