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

fix: 🐛 Remove nearest endpoints fetching #224

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
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
20 changes: 10 additions & 10 deletions src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Transaction from "./transaction.js";
* @param query
* @param endpoint
*/
export async function rawGraphQLQuery(query: string, endpoint: string): Promise<any> {
export async function rawGraphQLQuery(query: string, endpoint: string | URL): Promise<any> {
const url = new URL("/api", endpoint);
return fetch(url, {
method: "POST",
Expand All @@ -36,7 +36,7 @@ export async function rawGraphQLQuery(query: string, endpoint: string): Promise<
* @param endpoint The Archethic API endpoint
* @returns {Promise<NearestEndpoint[]>} A list of nearest endpoints
*/
export async function getNearestEndpoints(endpoint: string): Promise<NearestEndpoint[]> {
export async function getNearestEndpoints(endpoint: string | URL): Promise<NearestEndpoint[]> {
const url = new URL("/api", endpoint);
return fetch(url, {
method: "POST",
Expand Down Expand Up @@ -68,7 +68,7 @@ export async function getNearestEndpoints(endpoint: string): Promise<NearestEndp
* @param address address to get the transaction index
* @param endpoint The Archethic API endpoint
*/
export async function getTransactionIndex(address: string | Uint8Array, endpoint: string): Promise<number> {
export async function getTransactionIndex(address: string | Uint8Array, endpoint: string | URL): Promise<number> {
address = maybeUint8ArrayToHex(address);

const url = new URL("/api", endpoint);
Expand Down Expand Up @@ -101,7 +101,7 @@ export async function getTransactionIndex(address: string | Uint8Array, endpoint
* @param endpoint The Archethic API endpoint
* @returns {Promise<string>} The balance of the address
*/
export async function getStorageNoncePublicKey(endpoint: string): Promise<string> {
export async function getStorageNoncePublicKey(endpoint: string | URL): Promise<string> {
const url = new URL("/api", endpoint);
return fetch(url, {
method: "POST",
Expand Down Expand Up @@ -136,7 +136,7 @@ export async function getStorageNoncePublicKey(endpoint: string): Promise<string
*/
export async function getTransactionOwnerships(
address: string | Uint8Array,
endpoint: string,
endpoint: string | URL,
last: boolean = false
): Promise<Ownership[]> {
address = maybeUint8ArrayToHex(address);
Expand Down Expand Up @@ -180,7 +180,7 @@ export async function getTransactionOwnerships(
* @param tokenAddress address of the token
* @param endpoint The Archethic API endpoint
*/
export async function getToken(tokenAddress: string | Uint8Array, endpoint: string): Promise<{} | Token> {
export async function getToken(tokenAddress: string | Uint8Array, endpoint: string | URL): Promise<{} | Token> {
tokenAddress = maybeUint8ArrayToHex(tokenAddress);

const url = new URL("/api", endpoint);
Expand Down Expand Up @@ -214,7 +214,7 @@ export async function getToken(tokenAddress: string | Uint8Array, endpoint: stri
* @param endpoint The Archethic API endpoint
* @param timestamp The timestamp of the data to get
*/
export async function getOracleData(endpoint: string, timestamp: undefined | number = undefined): Promise<OracleData> {
export async function getOracleData(endpoint: string | URL, timestamp: undefined | number = undefined): Promise<OracleData> {
let query;

if (timestamp === undefined) {
Expand Down Expand Up @@ -268,7 +268,7 @@ export async function getOracleData(endpoint: string, timestamp: undefined | num
* @param endpoint The Archethic API endpoint
* @param handler The handler to call when a new update is received
*/
export async function subscribeToOracleUpdates(endpoint: string, handler: Function): Promise<any> {
export async function subscribeToOracleUpdates(endpoint: string | URL, handler: Function): Promise<any> {
const { host, protocol } = new URL(endpoint);
const ws_protocol = protocol == "https:" ? "wss" : "ws";

Expand Down Expand Up @@ -299,7 +299,7 @@ export async function subscribeToOracleUpdates(endpoint: string, handler: Functi
* @param endpoint The Archethic API endpoint
* @param address The address to get the balance of
*/
export async function getBalance(address: string | Uint8Array, endpoint: string): Promise<Balance> {
export async function getBalance(address: string | Uint8Array, endpoint: string | URL): Promise<Balance> {
address = maybeUint8ArrayToHex(address);

const url = new URL("/api", endpoint);
Expand Down Expand Up @@ -332,7 +332,7 @@ export async function getBalance(address: string | Uint8Array, endpoint: string)
});
}

export async function getContractCode(address: string | Uint8Array, endpoint: string): Promise<string> {
export async function getContractCode(address: string | Uint8Array, endpoint: string | URL): Promise<string> {
address = maybeUint8ArrayToHex(address);

const url = new URL("/api", endpoint);
Expand Down
3 changes: 0 additions & 3 deletions src/api/wallet_rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ export class ArchethicWalletClient {

_dispatchConnectionState(state?: ConnectionState) {
const connectionState = state ?? this.connectionState
console.log(`Connection state updated : ${connectionState}`);
this._connectionStateEventTarget.dispatchEvent(new Event(connectionState));
}

Expand All @@ -100,8 +99,6 @@ export class ArchethicWalletClient {
*/
async connect(): Promise<void> {
return new Promise(async (resolve, reject) => {
console.log('Connection attempt');

if (this.connectionState != ConnectionState.Closed) {
return reject(new Error("Connection already established. Cancelling new connection request"));
}
Expand Down
2 changes: 0 additions & 2 deletions src/endpoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ export class EndpointFactory {
*/
build(endpoint: string | undefined): Endpoint {
if (endpoint === undefined) {
console.log('Using AWC client');
return new AWCEndpoint(
AWCWebBrowserExtension.awc ??
new ArchethicWalletClient(new AWCWebsocketStreamChannel(`ws://localhost:12345`))
Expand All @@ -26,7 +25,6 @@ export class EndpointFactory {

const url: URL = new URL(endpoint);
if (url.protocol === "http:" || url.protocol === "https:") {
console.log('Using direct endpoint');
return new DirectEndpoint(endpoint);
}

Expand Down
29 changes: 7 additions & 22 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ export default class Archethic {
rpcWallet: ArchethicWalletClient | undefined;
rpcNode: NodeRPCClient | undefined;
transaction: Transaction;
nearestEndpoints: Set<string>;
account: Account;
network: Network;

Expand All @@ -40,7 +39,6 @@ export default class Archethic {
}
this.account = new Account(this);
this.network = new Network(this);
this.nearestEndpoints = new Set<string>();
this.transaction = new Transaction(this);
this.rpcNode = new NodeRPCClient(this);
}
Expand All @@ -49,32 +47,19 @@ export default class Archethic {
if (this.endpoint instanceof AWCEndpoint) {
await this.endpoint.resolve();
}
const nodes = this.endpoint.nodeEndpoint === null ?
[] :
await Api.getNearestEndpoints(this.endpoint.nodeEndpoint.toString());

let nearestEndpoints = nodes.map(({ ip, port }) => {
return `http://${ip}:${port}`;
});

nearestEndpoints.push(this.endpoint.origin.toString()); // Add the main endpoint as fallback

this.nearestEndpoints = new Set(nearestEndpoints);
return this;
}

async requestNode(call: (endpoint: string) => Promise<any>): Promise<any> {
const node = this.nearestEndpoints.values().next().value;
async requestNode(call: (endpoint: URL) => Promise<any>): Promise<any> {
if (!this.endpoint.nodeEndpoint) {
throw new Error("Archethic node's endpoint is undefined");
}

try {
return await call(node);
return await call(this.endpoint.nodeEndpoint);
} catch (err) {
this.nearestEndpoints.delete(node);
if (this.nearestEndpoints.size == 0) {
console.log(err);
throw new Error("Cannot reach Archethic node");
}
return this.requestNode(call);
console.log(err);
throw new Error("Cannot reach Archethic node");
}
}
}
2 changes: 1 addition & 1 deletion src/transaction_sender.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export default class TransactionSender {

async send(
tx: TransactionBuilder,
endpoint: string,
endpoint: string | URL,
confirmationThreshold: number = 100,
timeout: number = 60
): Promise<TransactionSender> {
Expand Down
128 changes: 0 additions & 128 deletions tests/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,132 +14,4 @@ describe("Archethic", () => {
expect(archethic.transaction).not.toBeUndefined();
});

describe("connect", () => {
it("should request endpoint to get list of nearest nodes", async () => {
nock("http://localhost:4000", {})
.post("/api", {
query: `query {
nearestEndpoints {
ip,
port
}
}`
})
.reply(200, {
data: {
nearestEndpoints: [
{ ip: "localhost", port: 4000 },
{ ip: "30.193.101.100", port: 40000 }
]
}
});

const archethic = new Archethic("http://localhost:4000");
await archethic.connect();

expect(archethic.nearestEndpoints).toStrictEqual(
new Set(["http://localhost:4000", "http://30.193.101.100:40000"])
);
});
});

describe("requestNode", () => {
it("should request the first nearest node", async () => {
nock("http://localhost:4000", {})
.post("/api", {
query: `query {
nearestEndpoints {
ip,
port
}
}`
})
.reply(200, {
data: {
nearestEndpoints: [
{ ip: "localhost", port: 4000 },
{ ip: "30.193.101.100", port: 40000 }
]
}
});
const archethic = new Archethic("http://localhost:4000");
await archethic.connect();

nock("http://localhost:4000", {})
.post("/api", {
query: `query {
sharedSecrets {
storageNoncePublicKey
}
}`
})
.reply(200, {
data: {
sharedSecrets: {
storageNoncePublicKey: "publicKey"
}
}
});

const publicKey = await archethic.requestNode((endpoint) => {
return API.getStorageNoncePublicKey(endpoint);
});

expect(publicKey).toBe("publicKey");
});

it("should request the next nearest node when the first failed", async () => {
nock("http://localhost:4000", {})
.post("/api", {
query: `query {
nearestEndpoints {
ip,
port
}
}`
})
.reply(200, {
data: {
nearestEndpoints: [
{ ip: "localhost", port: 4000 },
{ ip: "30.193.101.100", port: 40000 }
]
}
});
const archethic = new Archethic("http://localhost:4000");
await archethic.connect();

nock("http://localhost:4000", {})
.post("/api", {
query: `query {
sharedSecrets {
storageNoncePublicKey
}
}`
})
.reply(500, "Internal Server Error");

nock("http://30.193.101.100:40000", {})
.post("/api", {
query: `query {
sharedSecrets {
storageNoncePublicKey
}
}`
})
.reply(200, {
data: {
sharedSecrets: {
storageNoncePublicKey: "publicKey"
}
}
});

const publicKey = await archethic.requestNode((endpoint) => {
return API.getStorageNoncePublicKey(endpoint);
});

expect(publicKey).toBe("publicKey");
});
});
});
Loading