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

Add Payment Hash to response and better error messages #51

Merged
merged 5 commits into from
Jan 22, 2024
Merged
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
29 changes: 29 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@

# production or development
NODE_ENV="production"
# local port the faucet will be hosted on
PORT=3000
# testnet websocket address - Fill in other test networks url if needed
RIPPLED_URI="wss://s.altnet.rippletest.net:51233"
# funding address & secret, using genesis account is not recommended, please prefund your faucet account
FUNDING_ADDRESS=
FUNDING_SECRET=
# default faucet funding amount
XRP_AMOUNT= 1000

# Big Query credentials
BIGQUERY_PRIVATE_KEY=""
BIGQUERY_CLIENT_EMAIL=""
BIGQUERY_PROJECT_ID=""
BIGQUERY_DATASET_ID = ""
BIGQUERY_TABLE_ID = ""

# Caspian credentials
CASPIAN_ENDPOINT=""
CASPIAN_API_KEY=""
CASPIAN_PRODUCER_NAME=""
CASPIAN_ENTITY_NAME=""
CASPIAN_SCHEMA_TYPE=""
CASPIAN_SCHEMA_VERSION=


11 changes: 10 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,23 @@ Funds new Testnet accounts

## Usage

### Run the server:
### Run the server (example):

#### command line
```
npm install
NODE_ENV="production" PORT=3000 RIPPLED_URI="wss://s.altnet.rippletest.net:51233" FUNDING_ADDRESS=rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe FUNDING_SECRET=<secret> XRP_AMOUNT=10000
npm start
```

#### using env file
or fill out `.env` file using `.env.example` and run
```
npm install
npm start

```

### Fund a new account:

```
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

35 changes: 26 additions & 9 deletions src/routes/accounts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,16 @@ export default async function (req: Request, res: Response) {
payment.DestinationTag = account.tag;
}

let transactionHash = fundingWallet.sign(payment).hash;
try {
let result;
try {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move the signing out of the the try. That way you dont have to create the variable paymentHash.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved it out, the purpose of having it there is that the hash should be different before and after submitting right? I could have an error statement catching signing errors too.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hash will be the same before and after

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

then we don't need signing

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Signing is used to add the signature field but that doesnt change the hash as far as I know.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The signature is among the data used to compute a transaction's identifying hash. Adding or changing the signature will change the transaction hash. Relatedly, you can learn about transaction malleability here. Generally speaking, I don't consider any given transaction to have a hash yet if it is not signed (yet).

The hash is the same before and after submitting, if you are submitting a signed transaction.

result = await submitPaymentWithTicket(payment, client, fundingWallet);
transactionHash = result.hash;
} catch (err) {
console.log(`${rTracer.id()} | Failed to submit payment: ${err}`);
console.log(
`${rTracer.id()} | Failed to submit payment ${transactionHash}: ${err}`
);
res.status(500).send({
error: "Unable to fund account. Try again later",
account,
Expand All @@ -83,11 +87,11 @@ export default async function (req: Request, res: Response) {
return;
}

const status = result.engine_result;

const status = result.result.engine_result;
const response: FundedResponse = {
account: account,
amount: Number(amount),
transactionHash: transactionHash,
};

if (wallet && wallet.seed) {
Expand All @@ -98,7 +102,7 @@ export default async function (req: Request, res: Response) {
console.log(
`${rTracer.id()} | Funded ${
account.address
} with ${amount} XRP (${status})`
} with ${amount} XRP (${status}), paymentHash: ${transactionHash}`
);

if (config.BIGQUERY_PROJECT_ID) {
Expand All @@ -109,6 +113,7 @@ export default async function (req: Request, res: Response) {
console.warn(`Failed to insert into BigQuery: ${error}`);
}
}

incrementTxCount();
res.send(response);
}
Expand All @@ -120,6 +125,7 @@ export default async function (req: Request, res: Response) {
});
}
}

async function insertIntoBigQuery(
account: Account,
amount: string,
Expand Down Expand Up @@ -173,20 +179,31 @@ async function submitPaymentWithTicket(
) {
let retryCount = 0;
let result;
let hash;
while (retryCount < maxRetries) {
payment.TicketSequence = await getTicket(client);
result = (await client.submit(payment, { wallet: fundingWallet })).result;
payment = await client.autofill(payment);
const { tx_blob: paymentBlob, hash: paymentHash } =
fundingWallet.sign(payment);
hash = paymentHash;
result = (await client.submit(paymentBlob)).result;
if (result.engine_result === "tefNO_TICKET") {
retryCount++;
console.log(`Retrying transaction (${retryCount}/${maxRetries})`);
} else {
console.log(`Retrying transaction ${hash} (${retryCount}/${maxRetries})`);
} else if (result.engine_result === "tesSUCCESS") {
break;
} else {
throw new Error(
`Failed to submit transaction ${hash} with ticket, error code: ${result.engine_result}`
);
}
}

if (retryCount >= maxRetries) {
throw new Error("Failed to submit transaction after multiple attempts");
throw new Error(
`Failed to submit transaction ${hash} with ticket after multiple attempts`
);
}

return result;
return { result, hash };
}
4 changes: 3 additions & 1 deletion src/ticket-queue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,9 @@ export async function getTicket(client: Client) {
})
.catch((error) => {
console.log(
`Failed to create tickets. Error: ${JSON.stringify(error)} Message: ${error?.message}`
`Failed to create tickets. Error: ${JSON.stringify(error)} Message: ${
error?.message
}`
);
});
}
Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ export interface Account {
export interface FundedResponse {
account: Account;
amount: number;
transactionHash: string;
seed?: string;
}
Loading