diff --git a/docs/account.md b/docs/account.md index 0b7d9812..09261583 100644 --- a/docs/account.md +++ b/docs/account.md @@ -80,20 +80,13 @@ Account.isValidPair("SIGNING_KEY", "ACCOUNT_NUMBER"); // returns true only if th ## Using Signed Data and Signed Messages -We have already talked about creating signatures, so let's learn how we can apply them to creating signed data and signed messages. Signed data and signed messages are very similar, with the only difference being that signed messages have an extra `node_identifier` property. Here is an example of us creating signed data and a signed message: +We have already talked about creating signatures, so let's learn how we can apply them to creating signed messages. Here is an example of us creating a signed message: > Note that all of the `signature` and `node_identifier` properties that we are generating are _almost_ random as we are not passing any arguments into the `Account` class. ```ts const account = new Account(); -account.createSignedData({ name: "Bacon" }); - -// { -// data: { name: 'Bacon' }, -// signature: '68202fd5336c57dd42ba116fbf4154b7ef797473c7bc04949fef943c37b7b448ababf22c94711cd5f0fc603f5bd7d10d4e96dff9c876599de9fe887dfffe6d01' -// } - account.createSignedMessage({ name: "Tuna" }); // { diff --git a/docs/bank.md b/docs/bank.md index 85ed8192..2f5f2b60 100644 --- a/docs/bank.md +++ b/docs/bank.md @@ -508,6 +508,7 @@ console.log(res); > If you don't understand upgradeRequest and upgradeNotice, check out the [documentation](https://thenewboston.com/guide/resync-process) at thenewboston.com + ## Getting the Bank's Primary Validator Simply use the `Bank.getBankPV` method which returns the formatted url of the Primary Validator @@ -525,4 +526,66 @@ Use the `Bank.getTxFee` method to get the transaction fee const bank = new tnb.Bank("http://143.110.137.54"); console.log(await bank.getTxFee()); // 1 + +## Crawl + +A network crawl is the process of browsing nodes in order to discover new one. A crawl can be triggered by any client, given that it knows the Node's signing key. + +### Retrieve Crawl Status + +To retrieve the current crawl status of the bank we can use the `getCrawlStatus()` method + +```ts +const crawlStatus = bank.getCrawlStatus(); + +console.log(crawlStatus); + +// { +// crawl_last_completed: '2021-03-29 14:07:26.218216+00:00', +// crawl_status: 'crawling', +// ip_address: '18.218.193.164', +// port: 80, +// protocol: 'http' +// } +``` + +### Start Crawl + +To initiate a network crawl we need to send a request to the bank using the `startCrawl()` method + +```ts +const bankNetworkId = new Account("BankNetworkIdSigingKey"); + +const response = bank.startCrawl(bankNetworkId); + +console.log(response); + +// { +// crawl_last_completed: '2021-03-29 14:07:26.218216+00:00', +// crawl_status: 'crawling', +// ip_address: '18.218.193.164', +// port: 80, +// protocol: 'http' +// } +``` + +### Stopping Crawl + +To stop the network crawl process we can send a request to the bank using the `stopCrawl()` method + +```ts +const bankNetworkId = new Account("BankNetworkIdSigingKey"); + +const response = bank.stopCrawl(bankNetworkId); + +console.log(response); + +// { +// crawl_last_completed: '2021-03-29 14:20:29.265859+00:00', +// crawl_status: 'stop_requested', +// ip_address: '18.218.193.164', +// port: 80, +// protocol: 'http' +// } + ``` diff --git a/docs/confirmation-validator.md b/docs/confirmation-validator.md index a6240abd..b794c4e3 100644 --- a/docs/confirmation-validator.md +++ b/docs/confirmation-validator.md @@ -2,20 +2,19 @@ In this section, we will look at the methods of the Primary Validator class, which extends the Validator class. ->It is recommended that you read the [documentation for the `Validator` Class](#Validator) Class first, to understand the base methods before reading this section. +> It is recommended that you read the [documentation for the `Validator` Class](#Validator) Class first, to understand the base methods before reading this section. - ## Get Bank Confirmation Services +## Get Bank Confirmation Services Confirmation Services are services rendered by a CV for validating a Bank's transactions -We can see what Banks are currently using a Confirmation Validators services and the details attached by using the `getBankConfirmationServices()` method - +We can see what Banks are currently using a Confirmation Validators services and the details attached by using the `getBankConfirmationServices()` method ```ts const CV = new tnb.ConfirmationValidator("http://54.177.174.219"); // retrive confirmation services handled by CV -const paginationOptions = { limit: 2, offset: 0 } +const paginationOptions = { limit: 2, offset: 0 }; const confirmationServices = await CV.getBankConfirmationServices(paginationOptions); console.log(confirmationServices); @@ -84,16 +83,15 @@ The Upgrade Request can be sent using the `sendUpgradeRequest()` method const CV = new tnb.ConfirmationValidator("http://54.177.174.219"); //the node identifier of the confirmation validator that is receiving the upgrade notice -const nodeIdentifier = "9bfa37627e2dba0ae48165b219e76ceaba036b3db8e84108af73a1cce01fad35" +const nodeIdentifier = "9bfa37627e2dba0ae48165b219e76ceaba036b3db8e84108af73a1cce01fad35"; //Account of current CV -const account = new tnb.Account(CV.getConfig().account_number, "fakeSigningKeyHex"); +const account = new tnb.Account(CV.getConfig().account_number, "fakeSigningKeyHex"); const response = await CV.sendUpgradeRequest(nodeIdentifier, account); console.log(response); - // Status Code 200 if the CV Accepted the request and upgraded to a Primary Validator // Status Code 400 if the CV Rejected the request @@ -129,5 +127,64 @@ console.log(response); */ ``` +## Crawl + +A network crawl is the process of browsing nodes in order to discover new one. A crawl can be triggered by any client, given that it knows the Node's signing key. + +### Retrieve Crawl Status + +To retrieve the current crawl status of the bank we can use the `getCrawlStatus()` method + +```ts +const crawlStatus = CV.getCrawlStatus(); + +console.log(crawlStatus); + +// { +// crawl_last_completed: '2021-03-29 14:07:26.218216+00:00', +// crawl_status: 'crawling', +// ip_address: '18.218.193.164', +// port: 80, +// protocol: 'http' +// } +``` + +### Start Crawl + +To initiate a network crawl we need to send a request to the bank using the `startCrawl()` method +```ts +const CV_NetworkId = new Account("BankNetworkIdSigingKey"); +const response = CV.startCrawl(CV_NetworkId); + +console.log(response); + +// { +// crawl_last_completed: '2021-03-29 14:07:26.218216+00:00', +// crawl_status: 'crawling', +// ip_address: '18.218.193.164', +// port: 80, +// protocol: 'http' +// } +``` + +### Stopping Crawl + +To stop the network crawl process we can send a request to the bank using the `stopCrawl()` method + +```ts +const CV_NetworkId = new Account("BankNetworkIdSigingKey"); + +const response = CV.stopCrawl(CV_NetworkId); + +console.log(response); + +// { +// crawl_last_completed: '2021-03-29 14:20:29.265859+00:00', +// crawl_status: 'stop_requested', +// ip_address: '18.218.193.164', +// port: 80, +// protocol: 'http' +// } +``` diff --git a/src/account.ts b/src/account.ts index de7286cb..a6df78e4 100644 --- a/src/account.ts +++ b/src/account.ts @@ -1,5 +1,5 @@ import { createAccountData, uint8arrayToHex, hexToUint8Array } from "./utils"; -import type { BlockData, BlockMessage, SignedData, SignedMessage, Transaction } from "./models"; +import type { BlockData, BlockMessage, SignedMessage, Transaction } from "./models"; import { sign } from "tweetnacl"; type AccountKeys = [Uint8Array, Uint8Array]; @@ -77,29 +77,16 @@ export class Account { return signature.substring(0, 128); } - /** - * Creates a signed data object. - * @param data the data to be used to generate the signature - * @returns the signed data object - */ - createSignedData(data: T): SignedData { - return { - data, - signature: this.createSignature(JSON.stringify(data)), - }; - } - /** * Creates a signed data message with the given data. * @param data the data to be passed along in the message * @returns the signed message */ createSignedMessage(data: T): SignedMessage { - const { data: _data, signature } = this.createSignedData(data); return { - data: _data, + message: data, node_identifier: this.accountNumberHex, - signature, + signature: this.createSignature(JSON.stringify(data)), }; } diff --git a/src/bank.ts b/src/bank.ts index 2e2018e1..f512a3dd 100644 --- a/src/bank.ts +++ b/src/bank.ts @@ -1,6 +1,7 @@ import { ServerNode } from "./server-node"; import { PrimaryValidator } from "./primary-validator"; import type { + CrawlCommand, PaginationOptions, BankConfigResponse, Transaction, @@ -81,6 +82,31 @@ export class Bank extends ServerNode { return await super.getData("/config"); } + /** Gets the current crawl status */ + async getCrawlStatus() { + return await super.getData("/crawl"); + } + + /** + * Sends a Post Request to the bank to start crawl process + * @param account An Account created with the Network Id Signing key of the current Bank + */ + async startCrawl(account: Account) { + const command: CrawlCommand = "start"; + + return await super._postCrawl(command, account); + } + + /** + * Sends a Post Request to the bank to start crawl process + * @param account An Account created with the Network Id Signing key of the current Bank + */ + async stopCrawl(account: Account) { + const command: CrawlCommand = "stop"; + + return await super._postCrawl(command, account); + } + /** * Gets the confirmation blocks for the given bank. * @param options The optional object for the pagination options. diff --git a/src/confirmation-validator.ts b/src/confirmation-validator.ts index 86a24463..92a97c99 100644 --- a/src/confirmation-validator.ts +++ b/src/confirmation-validator.ts @@ -1,6 +1,6 @@ import { Validator } from "./validator"; import type { Account } from "./account"; -import type { ConfirmationValidatorConfigResponse } from "./models"; +import type { ConfirmationValidatorConfigResponse, CrawlData, CrawlCommand } from "./models"; /** Used for connecting with and using confirmation validator server nodes. */ export class ConfirmationValidator extends Validator { @@ -9,6 +9,31 @@ export class ConfirmationValidator extends Validator { return await super.getData("/bank_confirmation_services"); } + /** Gets the current crawl status */ + async getCrawlStatus() { + return await super.getData("/crawl"); + } + + /** + * Sends a Post Request to the bank to start crawl process + * @param account An Account created with the Network Id Signing key of the current Confirmation Validator + */ + async startCrawl(account: Account) { + const command: CrawlCommand = "start"; + + return await super._postCrawl(command, account); + } + + /** + * Sends a Post Request to the bank to start crawl process + * @param account An Account created with the Network Id Signing key of the current Confirmation Validator + */ + async stopCrawl(account: Account) { + const command: CrawlCommand = "stop"; + + return await super._postCrawl(command, account); + } + // TODO: POST /confirmation_blocks /** diff --git a/src/models/crawl-data.ts b/src/models/crawl-data.ts new file mode 100644 index 00000000..ad6f79c3 --- /dev/null +++ b/src/models/crawl-data.ts @@ -0,0 +1,7 @@ +/** The model for crawl status. */ +export type CrawlCommand = "start" | "stop"; + +/** The model for crawl data. */ +export interface CrawlData { + crawl: CrawlCommand; +} diff --git a/src/models/index.ts b/src/models/index.ts index 7b57b979..6fe1ac8c 100644 --- a/src/models/index.ts +++ b/src/models/index.ts @@ -1,11 +1,11 @@ export type { AccountData } from "./account-data"; export type { BlockData } from "./block-data"; export type { BlockMessage } from "./block-message"; +export type { CrawlCommand, CrawlData } from "./crawl-data"; export type { ServerNodeOptions } from "./server-node-options"; export type { PaymentHandlerOptions } from "./payment-handler-options"; export type { AccountPaymentHandlerOptions } from "./account-payment-handler-options"; export type { PaginationOptions } from "./pagination-options"; -export type { SignedData } from "./signed-data"; export type { SignedMessage } from "./signed-message"; export type { Transaction } from "./transaction"; export * from "./responses"; diff --git a/src/models/responses/constants.ts b/src/models/responses/constants.ts index a714b408..b6892535 100644 --- a/src/models/responses/constants.ts +++ b/src/models/responses/constants.ts @@ -1,7 +1,7 @@ -export type NodeType = "BANK"; +export type NodeType = "BANK" | "CONFIRMATION_VALIDATOR" | "PRIMARY_VALIDATOR"; export type Version = "v1.0"; export type Protocol = "http" | "https"; -export type Port = string; +export type Port = number; export type Hex = string; export type Trust = string; export type Origin = string; diff --git a/src/models/responses/generic/crawl.ts b/src/models/responses/generic/crawl.ts new file mode 100644 index 00000000..e0f17094 --- /dev/null +++ b/src/models/responses/generic/crawl.ts @@ -0,0 +1,10 @@ +import type { Origin, Port, Protocol } from "../constants"; + +/** The response model for a crawl request. */ +export interface CrawlResponse { + crawl_last_completed: string; + crawl_status: string; + ip_address: Origin; + port: Port; + protocol: Protocol; +} diff --git a/src/models/signed-message.ts b/src/models/signed-message.ts index 021ac209..1fa7d3f8 100644 --- a/src/models/signed-message.ts +++ b/src/models/signed-message.ts @@ -1,6 +1,7 @@ -import type { SignedData } from "./signed-data"; +/** The interface for the signed message that can send data to the server nodes. */ -/** The interface for user authenticated messages. */ -export interface SignedMessage extends SignedData { +export interface SignedMessage { + message: T; node_identifier: string; + signature: string; } diff --git a/src/server-node.ts b/src/server-node.ts index 2fc841a3..4abf94ba 100644 --- a/src/server-node.ts +++ b/src/server-node.ts @@ -1,6 +1,8 @@ import axios from "axios"; import { formatUrl, formatDefaultOptions } from "./utils"; import type { + CrawlData, + CrawlCommand, PaginatedAccountEntry, PaginatedEntryMetadata, PaginatedResponse, @@ -10,6 +12,7 @@ import type { import type { Account } from "./account"; import type { Protocol } from "./models/responses/constants"; import { throwError } from "./utils"; +import { CrawlResponse } from "./models/responses/generic/crawl"; /** * Used internally for all server nodes. @@ -87,6 +90,18 @@ export abstract class ServerNode { return await this.getData("/config"); } + /** + * Sends the crawl Request. + * @param command Command for crawl request + * @param account An Account created with the Network Id Signing key of the current node */ + protected async _postCrawl(command: CrawlCommand, account: Account) { + const data: CrawlData = { + crawl: command, + }; + + return await this.postData("/crawl", account.createSignedMessage(data)); + } + /** * Sends a connection request to this current network with the data about the new server. * @param ipAddress the new server node's ip address diff --git a/tests/account.test.js b/tests/account.test.js index 18b94e80..8f5d9145 100644 --- a/tests/account.test.js +++ b/tests/account.test.js @@ -56,20 +56,6 @@ describe("Account", () => { ); }); - it("createSignedData(data)", () => { - const account = createDefaultAccount(); - assertAccountBasics(account); - assertAccountBasicValues(account, defaultAccount.signingKey, defaultAccount.accountNumber); - const signedData = account.createSignedData({ trust: "23.90" }); - expect(signedData).toStrictEqual({ - data: { - trust: "23.90", - }, - signature: - "2b8d39b2eb528a8667475ac363cb2c84e5aeadef21ba07a80bc7a0c53e4b926ad79de242601b7810407da562c8092889321d7af9ca71911abc5af14538344c06", - }); - }); - it("createSignedMessage(data)", () => { const account = createDefaultAccount(); assertAccountBasics(account);