Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

Commit

Permalink
fix: make sure zero address is always signed with the same key (#1117)
Browse files Browse the repository at this point in the history
  • Loading branch information
davidmurdoch authored Sep 7, 2021
1 parent ddbbe3f commit 047b2ca
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 58 deletions.
9 changes: 6 additions & 3 deletions src/chains/ethereum/ethereum/src/transaction-pool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,10 +208,13 @@ export default class TransactionPool extends Emittery.Typed<{}, "drain"> {

let fakePrivateKey: Buffer;
if (from.equals(ACCOUNT_ZERO)) {
fakePrivateKey = Buffer.allocUnsafe(32);
// allow signing with the 0x0 address
// allow signing with the 0x0 address...
// always sign with the same fake key, a 31 `0`s followed by a single
// `1`. The key is arbitrary. It just must not be all `0`s and must be
// deterministic.
// see: https://github.com/ethereumjs/ethereumjs-monorepo/issues/829#issue-674385636
fakePrivateKey[0] = 1;
fakePrivateKey = Buffer.allocUnsafe(32).fill(0, 0, 31);
fakePrivateKey[31] = 1;
} else {
fakePrivateKey = Buffer.concat([from, from.slice(0, 12)]);
}
Expand Down
96 changes: 96 additions & 0 deletions src/chains/ethereum/ethereum/tests/api/eth/sendTransaction.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,102 @@ describe("api", () => {
});
});
});

describe("unlocked accounts", () => {
it("can send transactions from an unlocked 0x0 address", async () => {
const ZERO_ADDRESS = "0x" + "0".repeat(40);
const provider = await getProvider({
miner: {
defaultGasPrice: 0
},
wallet: {
unlockedAccounts: [ZERO_ADDRESS]
}
});
const [from] = await provider.send("eth_accounts");
await provider.send("eth_subscribe", ["newHeads"]);
const initialZeroBalance = "0x1234";
await provider.send("eth_sendTransaction", [
{ from: from, to: ZERO_ADDRESS, value: initialZeroBalance }
]);
await provider.once("message");
const initialBalance = await provider.send("eth_getBalance", [
ZERO_ADDRESS
]);
assert.strictEqual(
initialBalance,
initialZeroBalance,
"Zero address's balance isn't correct"
);
const removeValueFromZeroAmount = "0x123";
await provider.send("eth_sendTransaction", [
{ from: ZERO_ADDRESS, to: from, value: removeValueFromZeroAmount }
]);
await provider.once("message");
const afterSendBalance = BigInt(
await provider.send("eth_getBalance", [ZERO_ADDRESS])
);
assert.strictEqual(
BigInt(initialZeroBalance) - BigInt(removeValueFromZeroAmount),
afterSendBalance,
"Zero address's balance isn't correct"
);
});

it("unlocks accounts via unlock_accounts (both string and numbered numbers)", async () => {
const p = await getProvider({
wallet: {
secure: true,
unlockedAccounts: ["0", 1]
}
});

const accounts = await p.send("eth_accounts");
const balance1_1 = await p.send("eth_getBalance", [accounts[1]]);
const badSend = async () => {
return p.send("eth_sendTransaction", [
{
from: accounts[2],
to: accounts[1],
value: "0x7b"
}
]);
};
await assert.rejects(
badSend,
"Error: authentication needed: password or unlock"
);

await p.send("eth_subscribe", ["newHeads"]);
await p.send("eth_sendTransaction", [
{
from: accounts[0],
to: accounts[1],
value: "0x7b"
}
]);

await p.once("message");

const balance1_2 = await p.send("eth_getBalance", [accounts[1]]);
assert.strictEqual(BigInt(balance1_1) + 123n, BigInt(balance1_2));

const balance0_1 = await p.send("eth_getBalance", [accounts[0]]);

await p.send("eth_sendTransaction", [
{
from: accounts[1],
to: accounts[0],
value: "0x7b"
}
]);

await p.once("message");

const balance0_2 = await p.send("eth_getBalance", [accounts[0]]);
assert.strictEqual(BigInt(balance0_1) + 123n, BigInt(balance0_2));
});
});
});
});
});
55 changes: 0 additions & 55 deletions src/chains/ethereum/ethereum/tests/temp-tests.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,61 +87,6 @@ describe("Random tests that are temporary!", () => {
);
});

it("unlocks accounts via unlock_accounts (both string and numbered numbers)", async () => {
const p = await getProvider({
wallet: {
mnemonic,
secure: true,
unlockedAccounts: ["0", 1]
}
});

const accounts = await p.send("eth_accounts");
const balance1_1 = await p.send("eth_getBalance", [accounts[1]]);
const badSend = async () => {
return p.send("eth_sendTransaction", [
{
from: accounts[2],
to: accounts[1],
value: "0x7b"
}
]);
};
await assert.rejects(
badSend,
"Error: authentication needed: password or unlock"
);

await p.send("eth_subscribe", ["newHeads"]);
await p.send("eth_sendTransaction", [
{
from: accounts[0],
to: accounts[1],
value: "0x7b"
}
]);

await p.once("message");

const balance1_2 = await p.send("eth_getBalance", [accounts[1]]);
assert.strictEqual(BigInt(balance1_1) + 123n, BigInt(balance1_2));

const balance0_1 = await p.send("eth_getBalance", [accounts[0]]);

await p.send("eth_sendTransaction", [
{
from: accounts[1],
to: accounts[0],
value: "0x7b"
}
]);

await p.once("message");

const balance0_2 = await p.send("eth_getBalance", [accounts[0]]);
assert.strictEqual(BigInt(balance0_1) + 123n, BigInt(balance0_2));
});

it("deploys contracts", async () => {
const contract = compile(join(__dirname, "./contracts/HelloWorld.sol"));

Expand Down

0 comments on commit 047b2ca

Please sign in to comment.