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: flaky e2e sample dapp and quick start #8768

Merged
merged 1 commit into from
Sep 30, 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
2 changes: 1 addition & 1 deletion yarn-project/cli-wallet/src/cmds/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export async function deploy(
partialAddress: partialAddress.toString(),
initializationHash: instance.initializationHash.toString(),
salt: salt.toString(),
transactionFee: deployed.transactionFee,
transactionFee: deployed.transactionFee?.toString(),
Copy link
Contributor Author

@sklppy88 sklppy88 Sep 25, 2024

Choose a reason for hiding this comment

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

Snuck this in as it was causing a fail in JSON serialization

});
} else {
log(`Contract deployed at ${address.toString()}`);
Expand Down
19 changes: 11 additions & 8 deletions yarn-project/end-to-end/Earthfile
Original file line number Diff line number Diff line change
Expand Up @@ -222,15 +222,18 @@ guides-dapp-testing:
LOCALLY
RUN ./scripts/e2e_compose_test.sh guides/dapp_testing.test.ts

# TODO intermittent failure
# guides-sample-dapp:
# LOCALLY
# RUN ./scripts/e2e_compose_test.sh sample-dapp
# The two tests below need to be separated, because there is some crosstalk between the two. TODO (#8813): Figure out why.
guides-sample-dapp-ci:
LOCALLY
RUN ./scripts/e2e_compose_test.sh sample-dapp/ci/index.test.mjs

# TODO currently hangs for hour+
# guides-up-quick-start:
# LOCALLY
# RUN ./scripts/e2e_compose_test.sh guides/up_quick_start.test.ts
guides-sample-dapp:
LOCALLY
RUN ./scripts/e2e_compose_test.sh sample-dapp/index.test.mjs

guides-up-quick-start:
LOCALLY
RUN ./scripts/e2e_compose_test.sh guides/up_quick_start.test.ts

bench-publish-rollup:
LOCALLY
Expand Down
82 changes: 34 additions & 48 deletions yarn-project/end-to-end/src/guides/up_quick_start.sh
Original file line number Diff line number Diff line change
@@ -1,74 +1,60 @@
#!/bin/bash
# Run locally from end-to-end folder while running anvil and sandbox with:
# PATH=$PATH:../node_modules/.bin ./src/guides/up_quick_start.sh

set -eux
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Replaced old aztec cli w/ new wallet

Copy link
Contributor

Choose a reason for hiding this comment

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

Love it!


LOCATION=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
export WALLET_DATA_DIRECTORY="${LOCATION}/up_quick_start"

aztec-wallet() {
node --no-warnings ../cli-wallet/dest/bin/index.js "$@"
}

# docs:start:declare-accounts
ACCOUNTS=$(aztec-cli get-accounts --json | jq -r '.[].address')
ALICE=$(echo "$ACCOUNTS" | sed -n 1p)
BOB=$(echo "$ACCOUNTS" | sed -n 2p)
ALICE_PRIVATE_KEY="0x2153536ff6628eee01cf4024889ff977a18d9fa61d0e414422f7681cf085c281"
aztec-wallet create-account -a alice
aztec-wallet create-account -a bob
# docs:end:declare-accounts

# docs:start:deploy
CONTRACT=$(aztec-cli deploy TokenContractArtifact --private-key $ALICE_PRIVATE_KEY --salt 0 --args $ALICE "TokenName" "TKN" 18 --json | jq -r '.address')
echo "Deployed contract at $CONTRACT"
aztec-cli check-deploy --contract-address $CONTRACT
DEPLOY_OUTPUT=$(aztec-wallet deploy ../noir-contracts.js/artifacts/token_contract-Token.json --args accounts:alice Test TST 18 -f alice)
TOKEN_ADDRESS=$(echo "$DEPLOY_OUTPUT" | grep -oE 'Contract deployed at 0x[0-9a-fA-F]+' | cut -d ' ' -f4)
echo "Deployed contract at $TOKEN_ADDRESS"
# docs:end:deploy

# docs:start:mint-private
SECRET="0x29bf6afaf29f61cbcf2a4fa7da97be481fb418dc08bdab5338839974beb7b49f"
SECRET_HASH="0x0921759afa747c9073f75df9688a17d271cef0d6ec51eacf70e112402c4db6cd"
MINT_AMOUNT=69
aztec-wallet create-secret -a shield

MINT_PRIVATE_OUTPUT=$(aztec-cli send mint_private \
--args 1000 $SECRET_HASH \
--contract-artifact TokenContractArtifact \
--contract-address $CONTRACT \
--private-key $ALICE_PRIVATE_KEY)
aztec-wallet send mint_private -ca last --args $MINT_AMOUNT secrets:shield:hash -f alice

MINT_PRIVATE_TX_HASH=$(echo "$MINT_PRIVATE_OUTPUT" | grep "Transaction hash:" | awk '{print $NF}')
aztec-wallet add-note TransparentNote pending_shields -ca last -t last -a alice -b $MINT_AMOUNT secrets:shield:hash

aztec-cli add-note \
$ALICE $CONTRACT 5 84114971101151129711410111011678111116101 $MINT_PRIVATE_TX_HASH \
--note 1000 $SECRET_HASH

aztec-cli send redeem_shield \
--args $ALICE 1000 $SECRET \
--contract-artifact TokenContractArtifact \
--contract-address $CONTRACT \
--private-key $ALICE_PRIVATE_KEY
aztec-wallet send redeem_shield -ca last --args accounts:alice $MINT_AMOUNT secrets:shield -f alice
# docs:end:mint-private

# docs:start:get-balance
aztec-cli call balance_of_private \
--args $ALICE \
--contract-artifact TokenContractArtifact \
--contract-address $CONTRACT
ALICE_BALANCE=$(aztec-wallet simulate balance_of_private -ca last --args accounts:alice -f alice)
if ! echo $ALICE_BALANCE | grep -q $MINT_AMOUNT; then
echo "Incorrect Alice balance after transaction (expected $MINT_AMOUNT but got $ALICE_BALANCE)"
exit 1
fi
# docs:end:get-balance

# docs:start:transfer
aztec-cli send transfer \
--args $ALICE $BOB 500 0 \
--contract-artifact TokenContractArtifact \
--contract-address $CONTRACT \
--private-key $ALICE_PRIVATE_KEY
TRANSFER_AMOUNT=42

aztec-cli call balance_of_private \
--args $ALICE \
--contract-artifact TokenContractArtifact \
--contract-address $CONTRACT

aztec-cli call balance_of_private \
--args $BOB \
--contract-artifact TokenContractArtifact \
--contract-address $CONTRACT
aztec-wallet send transfer -ca last --args accounts:bob $TRANSFER_AMOUNT -f alice
# docs:end:transfer

aztec-cli get-logs

# Test end result
BOB_BALANCE=$(aztec-cli call balance_of_private --args $BOB --contract-artifact TokenContractArtifact --contract-address $CONTRACT)
if ! echo $BOB_BALANCE | grep -q 500; then
echo "Incorrect Bob balance after transaction (expected 500 but got $BOB_BALANCE)"
ALICE_BALANCE=$(aztec-wallet simulate balance_of_private -ca last --args accounts:alice -f alice)
if ! echo $ALICE_BALANCE | grep -q "$(($MINT_AMOUNT - $TRANSFER_AMOUNT))"; then
echo "Incorrect Alice balance after transaction (expected 27 but got $ALICE_BALANCE)"
exit 1
fi

BOB_BALANCE=$(aztec-wallet simulate balance_of_private -ca last --args accounts:bob -f bob)
if ! echo $BOB_BALANCE | grep -q $TRANSFER_AMOUNT; then
echo "Incorrect Bob balance after transaction (expected $TRANSFER_AMOUNT but got $BOB_BALANCE)"
exit 1
fi
13 changes: 5 additions & 8 deletions yarn-project/end-to-end/src/guides/up_quick_start.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,11 @@ const { PXE_URL = '' } = process.env;
// Entrypoint for running the up-quick-start script on the CI
describe('guides/up_quick_start', () => {
// TODO: update to not use CLI
it.skip('works', async () => {
it('works', async () => {
await waitForPXE(createPXEClient(PXE_URL));
execSync(
`DEBUG="aztec:*" PXE_URL=\${PXE_URL:-http://localhost:8080} PATH=$PATH:../node_modules/.bin ./src/guides/up_quick_start.sh`,
{
shell: '/bin/bash',
stdio: 'inherit',
},
);
execSync(`DEBUG="aztec:*" PXE_URL=\${PXE_URL:-http://localhost:8080} ./src/guides/up_quick_start.sh`, {
shell: '/bin/bash',
stdio: 'inherit',
});
});
});
2 changes: 1 addition & 1 deletion yarn-project/end-to-end/src/sample-dapp/ci/index.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { createPXEClient, waitForPXE } from '@aztec/aztec.js';
import { deploy } from '../deploy.mjs';
import { main } from '../index.mjs';

const { PXE_URL = '' } = process.env;
const { PXE_URL = 'http://localhost:8080' } = process.env;

// Tests on our CI that all scripts included in the guide work fine
describe('sample-dapp', () => {
Expand Down
6 changes: 3 additions & 3 deletions yarn-project/end-to-end/src/sample-dapp/contracts.mjs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { AztecAddress, Contract, loadContractArtifact } from '@aztec/aztec.js';
import TokenContractJson from '@aztec/noir-contracts.js/artifacts/token_contract-Token' assert { type: 'json' };
import { AztecAddress } from '@aztec/aztec.js';
import { TokenContract } from '@aztec/noir-contracts.js/Token';

import { readFileSync } from 'fs';

// docs:start:get-tokens
export async function getToken(client) {
const addresses = JSON.parse(readFileSync('addresses.json'));
return Contract.at(AztecAddress.fromString(addresses.token), loadContractArtifact(TokenContractJson), client);
return TokenContract.at(AztecAddress.fromString(addresses.token), client);
}
// docs:end:get-tokens
13 changes: 6 additions & 7 deletions yarn-project/end-to-end/src/sample-dapp/deploy.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { getInitialTestAccountsWallets } from '@aztec/accounts/testing';
import { Contract, createPXEClient, loadContractArtifact } from '@aztec/aztec.js';
import TokenContractJson from '@aztec/noir-contracts.js/artifacts/token_contract-Token' assert { type: 'json' };
import { Contract, createPXEClient, loadContractArtifact, waitForPXE } from '@aztec/aztec.js';
import { TokenContract, TokenContractArtifact } from '@aztec/noir-contracts.js';

import { writeFileSync } from 'fs';
import { fileURLToPath } from 'url';
Expand All @@ -10,13 +10,12 @@ const { PXE_URL = 'http://localhost:8080' } = process.env;

async function main() {
const pxe = createPXEClient(PXE_URL);
await waitForPXE(pxe);

const [ownerWallet] = await getInitialTestAccountsWallets(pxe);
const ownerAddress = ownerWallet.getCompleteAddress();
const ownerAddress = ownerWallet.getAddress();

const TokenContractArtifact = loadContractArtifact(TokenContractJson);
const token = await Contract.deploy(ownerWallet, TokenContractArtifact, [ownerAddress, 'TokenName', 'TKN', 18])
.send()
.deployed();
const token = await TokenContract.deploy(ownerWallet, ownerAddress, 'TokenName', 'TKN', 18).send().deployed();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Putting this deployment in parity with the other times we deploy


console.log(`Token deployed at ${token.address.toString()}`);

Expand Down
43 changes: 22 additions & 21 deletions yarn-project/end-to-end/src/sample-dapp/index.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { getInitialTestAccountsWallets } from '@aztec/accounts/testing';
import { ExtendedNote, Fr, Note, computeSecretHash, createPXEClient } from '@aztec/aztec.js';
import { ExtendedNote, Fr, Note, computeSecretHash, createPXEClient, waitForPXE } from '@aztec/aztec.js';
import { fileURLToPath } from '@aztec/foundation/url';
import { TokenContract, TokenContractArtifact } from '@aztec/noir-contracts.js/Token';

import { getToken } from './contracts.mjs';

Expand All @@ -14,9 +15,11 @@ async function showAccounts(pxe) {
}

async function showPrivateBalances(pxe) {
const [owner] = await getInitialTestAccountsWallets(pxe);
const token = await getToken(owner);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

getToken actually expects a wallet, not a PXE


// docs:start:showPrivateBalances
const accounts = await pxe.getRegisteredAccounts();
const token = await getToken(pxe);

for (const account of accounts) {
// highlight-next-line:showPrivateBalances
Expand All @@ -37,19 +40,16 @@ async function mintPrivateFunds(pxe) {
const secretHash = await computeSecretHash(secret);
const receipt = await token.methods.mint_private(mintAmount, secretHash).send().wait();

const storageSlot = token.artifact.storageLayout['pending_shields'].slot;
const noteTypeId = token.artifact.notes['TransparentNote'].id;

const note = new Note([new Fr(mintAmount), secretHash]);
const extendedNote = new ExtendedNote(
note,
owner.getAddress(),
token.address,
storageSlot,
noteTypeId,
TokenContract.storage.pending_shields.slot,
TokenContract.notes.TransparentNote.id,
receipt.txHash,
);
await pxe.addNote(extendedNote);
await pxe.addNote(extendedNote, owner.getAddress());

await token.methods.redeem_shield(owner.getAddress(), mintAmount, secret).send().wait();

Expand All @@ -61,21 +61,21 @@ async function transferPrivateFunds(pxe) {
const [owner, recipient] = await getInitialTestAccountsWallets(pxe);
const token = await getToken(owner);

const tx = token.methods.transfer(owner.getAddress(), recipient.getAddress(), 1n, 0).send();
console.log(`Sent transfer transaction ${await tx.getTxHash()}`);
await showPrivateBalances(pxe);
console.log(`Sending transaction, awaiting transaction to be mined`);
const receipt = await token.methods.transfer(recipient.getAddress(), 1).send().wait();

console.log(`Awaiting transaction to be mined`);
const receipt = await tx.wait();
console.log(`Transaction has been mined on block ${receipt.blockNumber}`);
console.log(`Transaction ${receipt.txHash} has been mined on block ${receipt.blockNumber}`);
await showPrivateBalances(pxe);
// docs:end:transferPrivateFunds
}

async function showPublicBalances(pxe) {
const [owner] = await getInitialTestAccountsWallets(pxe);
const token = await getToken(owner);

// docs:start:showPublicBalances
const accounts = await pxe.getRegisteredAccounts();
const token = await getToken(pxe);

for (const account of accounts) {
// highlight-next-line:showPublicBalances
Expand All @@ -90,13 +90,12 @@ async function mintPublicFunds(pxe) {
const [owner] = await getInitialTestAccountsWallets(pxe);
const token = await getToken(owner);

const tx = token.methods.mint_public(owner.getAddress(), 100n).send();
console.log(`Sent mint transaction ${await tx.getTxHash()}`);
await showPublicBalances(pxe);

console.log(`Awaiting transaction to be mined`);
const receipt = await tx.wait();
console.log(`Transaction has been mined on block ${receipt.blockNumber}`);
console.log(`Sending transaction, awaiting transaction to be mined`);
const receipt = await token.methods.mint_public(owner.getAddress(), 100).send().wait();
console.log(`Transaction ${receipt.txHash} has been mined on block ${receipt.blockNumber}`);

await showPublicBalances(pxe);
// docs:end:mintPublicFunds

Expand All @@ -110,8 +109,10 @@ async function mintPublicFunds(pxe) {

async function main() {
const pxe = createPXEClient(PXE_URL);
const { chainId } = await pxe.getNodeInfo();
console.log(`Connected to chain ${chainId}`);
await waitForPXE(pxe);

const { l1ChainId } = await pxe.getNodeInfo();
console.log(`Connected to chain ${l1ChainId}`);

await showAccounts(pxe);

Expand Down
27 changes: 13 additions & 14 deletions yarn-project/end-to-end/src/sample-dapp/index.test.mjs
Original file line number Diff line number Diff line change
@@ -1,49 +1,48 @@
import { createAccount } from '@aztec/accounts/testing';
import { Contract, ExtendedNote, Fr, Note, computeSecretHash, createPXEClient, waitForPXE } from '@aztec/aztec.js';
import { TokenContractArtifact } from '@aztec/noir-contracts.js/Token';
import { TokenContract, TokenContractArtifact } from '@aztec/noir-contracts.js/Token';

const { PXE_URL = 'http://localhost:8080', ETHEREUM_HOST = 'http://localhost:8545' } = process.env;

describe('token', () => {
// docs:start:setup
let owner, recipient, token;

beforeAll(async () => {
const pxe = createPXEClient(PXE_URL);
await waitForPXE(pxe);
owner = await createAccount(pxe);
recipient = await createAccount(pxe);

token = await Contract.deploy(owner, TokenContractArtifact, [owner.getCompleteAddress(), 'TokenName', 'TKN', 18])
.send()
.deployed();
token = await TokenContract.deploy(owner, owner.getAddress(), 'TokenName', 'TKN', 18).send().deployed();

const initialBalance = 20n;
const initialBalance = 69;
const secret = Fr.random();
const secretHash = await computeSecretHash(secret);
const receipt = await token.methods.mint_private(initialBalance, secretHash).send().wait();

const storageSlot = token.artifact.storageLayout['pending_shields'].slot;
const noteTypeId = token.artifact.notes['TransparentNote'].id;
const note = new Note([new Fr(initialBalance), secretHash]);
const extendedNote = new ExtendedNote(
note,
owner.getAddress(),
token.address,
storageSlot,
noteTypeId,
TokenContract.storage.pending_shields.slot,
TokenContract.notes.TransparentNote.id,
receipt.txHash,
);
await pxe.addNote(extendedNote);
await pxe.addNote(extendedNote, owner.getAddress());

await token.methods.redeem_shield({ address: owner.getAddress() }, initialBalance, secret).send().wait();
await token.methods.redeem_shield(owner.getAddress(), initialBalance, secret).send().wait();
}, 120_000);
// docs:end:setup

// docs:start:test
it('increases recipient funds on transfer', async () => {
expect(await token.methods.balance_of_private(recipient.getAddress()).simulate()).toEqual(0n);
await token.methods.transfer(owner.getAddress(), recipient.getAddress(), 20n, 0).send().wait();
expect(await token.methods.balance_of_private(recipient.getAddress()).simulate()).toEqual(20n);
expect(await token.withWallet(recipient).methods.balance_of_private(recipient.getAddress()).simulate()).toEqual(0n);
await token.methods.transfer(recipient.getAddress(), 20).send().wait();
expect(await token.withWallet(recipient).methods.balance_of_private(recipient.getAddress()).simulate()).toEqual(
20n,
);
}, 30_000);
// docs:end:test
});
4 changes: 3 additions & 1 deletion yarn-project/pxe/src/database/kv_pxe_database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,9 @@ export class KVPxeDatabase implements PxeDatabase {
return true;
}

addCompleteAddress(completeAddress: CompleteAddress): Promise<boolean> {
async addCompleteAddress(completeAddress: CompleteAddress): Promise<boolean> {
await this.#addScope(completeAddress.address);
Copy link
Contributor Author

@sklppy88 sklppy88 Sep 25, 2024

Choose a reason for hiding this comment

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

We needed this because sample_app was sometimes failing without it, because it would try to get_notes we haven't received anything for yet. We should be adding a scope when we add a complete address either way.


return this.#db.transaction(() => {
const addressString = completeAddress.address.toString();
const buffer = completeAddress.toBuffer();
Expand Down
Loading