Commit d040a8d9 authored by Michael-Vander-Meiden's avatar Michael-Vander-Meiden Committed by GitHub

Deleted update functions, helper internal functions, and tests. added changeset (#2389)

Co-authored-by: default avatarMaurelian <maurelian@protonmail.ch>
parent 32cf1dc9
---
'@eth-optimism/contracts': patch
---
Deleted update and helper functions/tests from Lib_MerkleTrie.sol and Lib_SecureMerkleTrie.sol
...@@ -34,27 +34,6 @@ library Lib_SecureMerkleTrie { ...@@ -34,27 +34,6 @@ library Lib_SecureMerkleTrie {
return Lib_MerkleTrie.verifyInclusionProof(key, _value, _proof, _root); return Lib_MerkleTrie.verifyInclusionProof(key, _value, _proof, _root);
} }
/**
* @notice Updates a Merkle trie and returns a new root hash.
* @param _key Key of the node to update, as a hex string.
* @param _value Value of the node to update, as a hex string.
* @param _proof Merkle trie inclusion proof for the node *nearest* the
* target node. If the key exists, we can simply update the value.
* Otherwise, we need to modify the trie to handle the new k/v pair.
* @param _root Known root of the Merkle trie. Used to verify that the
* included proof is correctly constructed.
* @return _updatedRoot Root hash of the newly constructed trie.
*/
function update(
bytes memory _key,
bytes memory _value,
bytes memory _proof,
bytes32 _root
) internal pure returns (bytes32 _updatedRoot) {
bytes memory key = _getSecureKey(_key);
return Lib_MerkleTrie.update(key, _value, _proof, _root);
}
/** /**
* @notice Retrieves the value associated with a given key. * @notice Retrieves the value associated with a given key.
* @param _key Key to search for, as hex bytes. * @param _key Key to search for, as hex bytes.
...@@ -72,21 +51,6 @@ library Lib_SecureMerkleTrie { ...@@ -72,21 +51,6 @@ library Lib_SecureMerkleTrie {
return Lib_MerkleTrie.get(key, _proof, _root); return Lib_MerkleTrie.get(key, _proof, _root);
} }
/**
* Computes the root hash for a trie with a single node.
* @param _key Key for the single node.
* @param _value Value for the single node.
* @return _updatedRoot Hash of the trie.
*/
function getSingleNodeRootHash(bytes memory _key, bytes memory _value)
internal
pure
returns (bytes32 _updatedRoot)
{
bytes memory key = _getSecureKey(_key);
return Lib_MerkleTrie.getSingleNodeRootHash(key, _value);
}
/********************* /*********************
* Private Functions * * Private Functions *
*********************/ *********************/
......
...@@ -17,15 +17,6 @@ contract TestLib_MerkleTrie { ...@@ -17,15 +17,6 @@ contract TestLib_MerkleTrie {
return Lib_MerkleTrie.verifyInclusionProof(_key, _value, _proof, _root); return Lib_MerkleTrie.verifyInclusionProof(_key, _value, _proof, _root);
} }
function update(
bytes memory _key,
bytes memory _value,
bytes memory _proof,
bytes32 _root
) public pure returns (bytes32) {
return Lib_MerkleTrie.update(_key, _value, _proof, _root);
}
function get( function get(
bytes memory _key, bytes memory _key,
bytes memory _proof, bytes memory _proof,
...@@ -33,12 +24,4 @@ contract TestLib_MerkleTrie { ...@@ -33,12 +24,4 @@ contract TestLib_MerkleTrie {
) public pure returns (bool, bytes memory) { ) public pure returns (bool, bytes memory) {
return Lib_MerkleTrie.get(_key, _proof, _root); return Lib_MerkleTrie.get(_key, _proof, _root);
} }
function getSingleNodeRootHash(bytes memory _key, bytes memory _value)
public
pure
returns (bytes32)
{
return Lib_MerkleTrie.getSingleNodeRootHash(_key, _value);
}
} }
...@@ -17,15 +17,6 @@ contract TestLib_SecureMerkleTrie { ...@@ -17,15 +17,6 @@ contract TestLib_SecureMerkleTrie {
return Lib_SecureMerkleTrie.verifyInclusionProof(_key, _value, _proof, _root); return Lib_SecureMerkleTrie.verifyInclusionProof(_key, _value, _proof, _root);
} }
function update(
bytes memory _key,
bytes memory _value,
bytes memory _proof,
bytes32 _root
) public pure returns (bytes32) {
return Lib_SecureMerkleTrie.update(_key, _value, _proof, _root);
}
function get( function get(
bytes memory _key, bytes memory _key,
bytes memory _proof, bytes memory _proof,
...@@ -33,12 +24,4 @@ contract TestLib_SecureMerkleTrie { ...@@ -33,12 +24,4 @@ contract TestLib_SecureMerkleTrie {
) public pure returns (bool, bytes memory) { ) public pure returns (bool, bytes memory) {
return Lib_SecureMerkleTrie.get(_key, _proof, _root); return Lib_SecureMerkleTrie.get(_key, _proof, _root);
} }
function getSingleNodeRootHash(bytes memory _key, bytes memory _value)
public
pure
returns (bytes32)
{
return Lib_SecureMerkleTrie.getSingleNodeRootHash(_key, _value);
}
} }
...@@ -2,14 +2,11 @@ ...@@ -2,14 +2,11 @@
import * as rlp from 'rlp' import * as rlp from 'rlp'
import { ethers } from 'hardhat' import { ethers } from 'hardhat'
import { Contract } from 'ethers' import { Contract } from 'ethers'
import { fromHexString, toHexString } from '@eth-optimism/core-utils' import { toHexString } from '@eth-optimism/core-utils'
import { Trie } from 'merkle-patricia-tree/dist/baseTrie'
/* Internal Imports */ /* Internal Imports */
import { expect } from '../../../setup' import { expect } from '../../../setup'
import { TrieTestGenerator } from '../../../helpers' import { TrieTestGenerator } from '../../../helpers'
import * as officialTestJson from '../../../data/json/libraries/trie/trietest.json'
import * as officialTestAnyOrderJson from '../../../data/json/libraries/trie/trieanyorder.json'
const NODE_COUNTS = [1, 2, 32, 128] const NODE_COUNTS = [1, 2, 32, 128]
...@@ -22,100 +19,6 @@ describe('Lib_MerkleTrie', () => { ...@@ -22,100 +19,6 @@ describe('Lib_MerkleTrie', () => {
}) })
// Eth-foundation tests: https://github.com/ethereum/tests/tree/develop/TrieTests // Eth-foundation tests: https://github.com/ethereum/tests/tree/develop/TrieTests
describe('official tests', () => {
for (const testName of Object.keys(officialTestJson.tests)) {
it(`should perform official test: ${testName}`, async () => {
const trie = new Trie()
const inputs = officialTestJson.tests[testName].in
const expected = officialTestJson.tests[testName].root
for (const input of inputs) {
let key: Buffer
if (input[0].startsWith('0x')) {
key = fromHexString(input[0])
} else {
key = fromHexString(
ethers.utils.hexlify(ethers.utils.toUtf8Bytes(input[0]))
)
}
let val: Buffer
if (input[1] === null) {
throw new Error('deletions not supported, check your tests')
} else if (input[1].startsWith('0x')) {
val = fromHexString(input[1])
} else {
val = fromHexString(
ethers.utils.hexlify(ethers.utils.toUtf8Bytes(input[1]))
)
}
const proof = await Trie.createProof(trie, key)
const root = trie.root
await trie.put(key, val)
const out = await Lib_MerkleTrie.update(
toHexString(key),
toHexString(val),
toHexString(rlp.encode(proof)),
root
)
expect(out).to.equal(toHexString(trie.root))
}
expect(toHexString(trie.root)).to.equal(expected)
})
}
})
describe('official tests - trie any order', () => {
for (const testName of Object.keys(officialTestAnyOrderJson.tests)) {
it(`should perform official test: ${testName}`, async () => {
const trie = new Trie()
const inputs = officialTestAnyOrderJson.tests[testName].in
const expected = officialTestAnyOrderJson.tests[testName].root
for (const input of Object.keys(inputs)) {
let key: Buffer
if (input.startsWith('0x')) {
key = fromHexString(input)
} else {
key = fromHexString(
ethers.utils.hexlify(ethers.utils.toUtf8Bytes(input))
)
}
let val: Buffer
if (inputs[input] === null) {
throw new Error('deletions not supported, check your tests')
} else if (inputs[input].startsWith('0x')) {
val = fromHexString(inputs[input])
} else {
val = fromHexString(
ethers.utils.hexlify(ethers.utils.toUtf8Bytes(inputs[input]))
)
}
const proof = await Trie.createProof(trie, key)
const root = trie.root
await trie.put(key, val)
const out = await Lib_MerkleTrie.update(
toHexString(key),
toHexString(val),
toHexString(rlp.encode(proof)),
root
)
expect(out).to.equal(toHexString(trie.root))
}
expect(toHexString(trie.root)).to.equal(expected)
})
}
})
describe('verifyInclusionProof', () => { describe('verifyInclusionProof', () => {
for (const nodeCount of NODE_COUNTS) { for (const nodeCount of NODE_COUNTS) {
describe(`inside a trie with ${nodeCount} nodes and keys/vals of size ${nodeCount} bytes`, () => { describe(`inside a trie with ${nodeCount} nodes and keys/vals of size ${nodeCount} bytes`, () => {
...@@ -152,62 +55,6 @@ describe('Lib_MerkleTrie', () => { ...@@ -152,62 +55,6 @@ describe('Lib_MerkleTrie', () => {
} }
}) })
describe('update', () => {
for (const nodeCount of NODE_COUNTS) {
describe(`inside a trie with ${nodeCount} nodes and keys/vals of size ${nodeCount} bytes`, () => {
let generator: TrieTestGenerator
before(async () => {
generator = await TrieTestGenerator.fromRandom({
seed: `seed.update.${nodeCount}`,
nodeCount,
secure: false,
keySize: nodeCount,
valSize: nodeCount,
})
})
for (
let i = 0;
i < nodeCount;
i += nodeCount / (nodeCount > 8 ? 8 : 1)
) {
it(`should correctly update node #${i}`, async () => {
const test = await generator.makeNodeUpdateTest(
i,
'0x1234123412341234'
)
expect(
await Lib_MerkleTrie.update(
test.key,
test.val,
test.proof,
test.root
)
).to.equal(test.newRoot)
})
}
})
}
it('should return the single-node root hash if the trie was previously empty', async () => {
const key = '0x1234'
const val = '0x5678'
const trie = new Trie()
await trie.put(fromHexString(key), fromHexString(val))
expect(
await Lib_MerkleTrie.update(
key,
val,
'0x', // Doesn't require a proof
ethers.utils.keccak256('0x80') // Empty Merkle trie root hash
)
).to.equal(toHexString(trie.root))
})
})
describe('get', () => { describe('get', () => {
for (const nodeCount of NODE_COUNTS) { for (const nodeCount of NODE_COUNTS) {
describe(`inside a trie with ${nodeCount} nodes and keys/vals of size ${nodeCount} bytes`, () => { describe(`inside a trie with ${nodeCount} nodes and keys/vals of size ${nodeCount} bytes`, () => {
......
...@@ -50,43 +50,6 @@ describe('Lib_SecureMerkleTrie', () => { ...@@ -50,43 +50,6 @@ describe('Lib_SecureMerkleTrie', () => {
} }
}) })
describe('update', () => {
for (const nodeCount of NODE_COUNTS) {
describe(`inside a trie with ${nodeCount} nodes`, () => {
let generator: TrieTestGenerator
before(async () => {
generator = await TrieTestGenerator.fromRandom({
seed: `seed.update.${nodeCount}`,
nodeCount,
secure: true,
})
})
for (
let i = 0;
i < nodeCount;
i += nodeCount / (nodeCount > 8 ? 8 : 1)
) {
it(`should correctly update node #${i}`, async () => {
const test = await generator.makeNodeUpdateTest(
i,
'0x1234123412341234'
)
expect(
await Lib_SecureMerkleTrie.update(
test.key,
test.val,
test.proof,
test.root
)
).to.equal(test.newRoot)
})
}
})
}
})
describe('get', () => { describe('get', () => {
for (const nodeCount of NODE_COUNTS) { for (const nodeCount of NODE_COUNTS) {
describe(`inside a trie with ${nodeCount} nodes`, () => { describe(`inside a trie with ${nodeCount} nodes`, () => {
...@@ -115,22 +78,4 @@ describe('Lib_SecureMerkleTrie', () => { ...@@ -115,22 +78,4 @@ describe('Lib_SecureMerkleTrie', () => {
}) })
} }
}) })
describe('getSingleNodeRootHash', () => {
let generator: TrieTestGenerator
before(async () => {
generator = await TrieTestGenerator.fromRandom({
seed: `seed.get.${1}`,
nodeCount: 1,
secure: true,
})
})
it(`should get the root hash of a trie with a single node`, async () => {
const test = await generator.makeInclusionProofTest(0)
expect(
await Lib_SecureMerkleTrie.getSingleNodeRootHash(test.key, test.val)
).to.equal(test.root)
})
})
}) })
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment