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

Let EthereumConnection.getAccount return undefined when balance is 0 #774

Merged
merged 1 commit into from
Feb 26, 2019
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
by transaction ID.
* @iov/ethereum: Transaction parsing now works for pre-EIP155 signatures
* @iov/ethereum: Let listenTx/liveTx return signer's pubkey
* @iov/ethereum: Let `.getAccount` return undefined when balance is 0

## 0.12.1

Expand Down
35 changes: 14 additions & 21 deletions packages/iov-ethereum/src/ethereumconnection.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,23 +194,19 @@ describe("EthereumConnection", () => {
it("can get account from unused address", async () => {
pendingWithoutEthereum();
const connection = await EthereumConnection.establish(testConfig.base);
const account = await connection.getAccount({ address: testConfig.unusedAddress });

// At the moment we cannot distinguish between unused account and balance 0
expect(account).toBeDefined();
expect(account!.balance[0].quantity).toEqual("0");
const account = await connection.getAccount({ address: testConfig.unusedAddress });
expect(account).toBeUndefined();

connection.disconnect();
});

it("can get account from unused pubkey", async () => {
pendingWithoutEthereum();
const connection = await EthereumConnection.establish(testConfig.base);
const account = await connection.getAccount({ pubkey: testConfig.unusedPubkey });

// At the moment we cannot distinguish between unused account and balance 0
expect(account).toBeDefined();
expect(account!.balance[0].quantity).toEqual("0");
const account = await connection.getAccount({ pubkey: testConfig.unusedPubkey });
expect(account).toBeUndefined();

connection.disconnect();
});
Expand Down Expand Up @@ -472,25 +468,22 @@ describe("EthereumConnection", () => {
const recipient = await randomAddress();

// setup watching
const events = new Array<Account>();
const events = new Array<Account | undefined>();
const subscription = connection.watchAccount({ address: recipient }).subscribe({
next: event => {
if (!event) {
subscription.unsubscribe();
connection.disconnect();
done.fail("Received event undefined, which is not expected in Ethereum");
return;
}
events.push(event);

expect(event.address).toEqual(recipient);
expect(event.balance.length).toEqual(1);
expect(event.balance[0].fractionalDigits).toEqual(18);
expect(event.balance[0].tokenTicker).toEqual("ETH");
if (event) {
expect(event.address).toEqual(recipient);
expect(event.balance.length).toEqual(1);
expect(event.balance[0].fractionalDigits).toEqual(18);
expect(event.balance[0].tokenTicker).toEqual("ETH");
}

if (events.length === 2) {
expect(events[0].balance[0].quantity).toEqual("0");
expect(events[1].balance[0].quantity).toEqual(defaultAmount.quantity);
expect(events[0]).toBeUndefined();
expect(events[1]).toBeDefined();
expect(events[1]!.balance[0].quantity).toEqual(defaultAmount.quantity);

subscription.unsubscribe();
connection.disconnect();
Expand Down
11 changes: 10 additions & 1 deletion packages/iov-ethereum/src/ethereumconnection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,14 +212,23 @@ export class EthereumConnection implements BcpConnection {
}

// eth_getBalance always returns one result. Balance is 0x0 if account does not exist.
const ethBalance = Parse.ethereumAmount(decodeHexQuantityString(response.result));

// Assume the account does not exist when balance is 0. This can lead to cases
// where undefined is returned even if the account exists. Keep this as a
// workaround until we have a clever and fast way to check account existence.
// https://github.com/iov-one/iov-core/issues/676
if (ethBalance.quantity === "0") {
return undefined;
}

const account: Account = {
address: address,
pubkey: undefined, // TODO: get from a transaction sent by this address
balance: [
{
tokenName: constants.primaryTokenName,
...Parse.ethereumAmount(decodeHexQuantityString(response.result)),
...ethBalance,
},
],
};
Expand Down