Skip to content

Commit

Permalink
update to mpt v4
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanio committed Jun 25, 2020
1 parent b6beae4 commit 67a85b2
Show file tree
Hide file tree
Showing 23 changed files with 480 additions and 1,404 deletions.
410 changes: 0 additions & 410 deletions packages/account/package-lock.json

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion packages/account/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@
"@types/bn.js": "^4.11.6",
"@types/node": "^11.13.4",
"@types/tape": "^4.13.0",
"merkle-patricia-tree": "^3.0.0",
"nyc": "^14.0.0",
"prettier": "^2.0.5",
"tape": "^4.10.1",
Expand Down
149 changes: 6 additions & 143 deletions packages/account/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,7 @@
import * as rlp from 'rlp'

const ethUtil = require('ethereumjs-util')
import { KECCAK256_NULL, KECCAK256_NULL_S, KECCAK256_RLP, defineProperties } from 'ethereumjs-util'
const Buffer = require('safe-buffer').Buffer

interface TrieGetCb {
(err: any, value: Buffer | null): void
}
interface TriePutCb {
(err?: any): void
}

interface Trie {
root: Buffer
copy(): Trie
getRaw(key: Buffer, cb: TrieGetCb): void
putRaw(key: Buffer | string, value: Buffer, cb: TriePutCb): void
get(key: Buffer | string, cb: TrieGetCb): void
put(key: Buffer | string, value: Buffer | string, cb: TriePutCb): void
}

export default class Account {
/**
* The account's nonce.
Expand Down Expand Up @@ -80,160 +63,40 @@ export default class Account {
{
name: 'stateRoot',
length: 32,
default: ethUtil.KECCAK256_RLP,
default: KECCAK256_RLP,
},
{
name: 'codeHash',
length: 32,
default: ethUtil.KECCAK256_NULL,
default: KECCAK256_NULL,
},
]

ethUtil.defineProperties(this, fields, data)
defineProperties(this, fields, data)
}

/**
* Returns the RLP serialization of the account as a `Buffer`.
*
*/
serialize(): Buffer {
return rlp.encode([this.nonce, this.balance, this.stateRoot, this.codeHash])
}

/**
* Returns a `Boolean` deteremining if the account is a contract.
*
*/
isContract(): boolean {
return this.codeHash.toString('hex') !== ethUtil.KECCAK256_NULL_S
}

/**
* Fetches the code from the trie.
* @param trie The [trie](https://github.com/ethereumjs/merkle-patricia-tree) storing the accounts
* @param cb The callback
*/
getCode(trie: Trie, cb: TrieGetCb): void {
if (!this.isContract()) {
cb(null, Buffer.alloc(0))
return
}

trie.getRaw(this.codeHash, cb)
}

/**
* Stores the code in the trie.
*
* ~~~
* // Requires manual merkle-patricia-tree install
* const SecureTrie = require('merkle-patricia-tree/secure')
* const Account = require('./index.js').default
*
* let code = Buffer.from(
* '73095e7baea6a6c7c4c2dfeb977efac326af552d873173095e7baea6a6c7c4c2dfeb977efac326af552d873157',
* 'hex',
* )
*
* let raw = {
* nonce: '0x0',
* balance: '0x03e7',
* stateRoot: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421',
* codeHash: '0xb30fb32201fe0486606ad451e1a61e2ae1748343cd3d411ed992ffcc0774edd4',
* }
* let account = new Account(raw)
* let trie = new SecureTrie()
*
* account.setCode(trie, code, function(err, codeHash) {
* console.log(`Code with hash 0x${codeHash.toString('hex')} set to trie`)
* account.getCode(trie, function(err, code) {
* console.log(`Code ${code.toString('hex')} read from trie`)
* })
* })
* ~~~
*
* @param trie The [trie](https://github.com/ethereumjs/merkle-patricia-tree) storing the accounts.
* @param {Buffer} code
* @param cb The callback.
*
*/
setCode(trie: Trie, code: Buffer, cb: (err: any, codeHash: Buffer) => void): void {
this.codeHash = ethUtil.keccak256(code)

if (this.codeHash.toString('hex') === ethUtil.KECCAK256_NULL_S) {
cb(null, Buffer.alloc(0))
return
}

trie.putRaw(this.codeHash, code, (err: any) => {
cb(err, this.codeHash)
})
}

/**
* Fetches `key` from the account's storage.
* @param trie
* @param key
* @param cb
*/
getStorage(trie: Trie, key: Buffer | string, cb: TrieGetCb) {
const t = trie.copy()
t.root = this.stateRoot
t.get(key, cb)
}

/**
* Stores a `val` at the `key` in the contract's storage.
*
* Example for `getStorage` and `setStorage`:
*
* ~~~
* // Requires manual merkle-patricia-tree install
* const SecureTrie = require('merkle-patricia-tree/secure')
* const Account = require('./index.js').default
*
* let raw = {
* nonce: '0x0',
* balance: '0x03e7',
* stateRoot: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421',
* codeHash: '0xb30fb32201fe0486606ad451e1a61e2ae1748343cd3d411ed992ffcc0774edd4',
* }
* let account = new Account(raw)
* let trie = new SecureTrie()
* let key = Buffer.from('0000000000000000000000000000000000000000', 'hex')
* let value = Buffer.from('01', 'hex')
*
* account.setStorage(trie, key, value, function(err) {
* account.getStorage(trie, key, function(err, value) {
* console.log(`Value ${value.toString('hex')} set and retrieved from trie.`)
* })
* })
* ~~~
*
* @param trie
* @param key
* @param val
* @param cb
*/
setStorage(trie: Trie, key: Buffer | string, val: Buffer | string, cb: TriePutCb) {
const t = trie.copy()
t.root = this.stateRoot
t.put(key, val, (err: any) => {
if (err) return cb(err)
this.stateRoot = t.root
cb()
})
return this.codeHash.toString('hex') !== KECCAK256_NULL_S
}

/**
* Returns a `Boolean` determining if the account is empty.
*
*/
isEmpty(): boolean {
return (
this.balance.toString('hex') === '' &&
this.nonce.toString('hex') === '' &&
this.codeHash.toString('hex') === ethUtil.KECCAK256_NULL_S
this.codeHash.toString('hex') === KECCAK256_NULL_S
)
}
}
75 changes: 0 additions & 75 deletions packages/account/test/index.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import * as tape from 'tape'
import * as rlp from 'rlp'
import Account from '../src/index'
const SecureTrie = require('merkle-patricia-tree/secure')

tape('empty constructor', function (tester) {
const it = tester.test
Expand Down Expand Up @@ -132,80 +131,6 @@ tape('isContract', function (tester) {
})
})

tape('setCode && getCode', (tester) => {
const it = tester.test
it('should set and get code', (t) => {
const code = Buffer.from(
'73095e7baea6a6c7c4c2dfeb977efac326af552d873173095e7baea6a6c7c4c2dfeb977efac326af552d873157',
'hex',
)

const raw = {
nonce: '0x0',
balance: '0x03e7',
stateRoot: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421',
codeHash: '0xb30fb32201fe0486606ad451e1a61e2ae1748343cd3d411ed992ffcc0774edd4',
}
const account = new Account(raw)
const trie = new SecureTrie()

account.setCode(trie, code, function (err, codeHash) {
account.getCode(trie, function (err, codeRetrieved) {
t.equals(Buffer.compare(code, codeRetrieved!), 0)
t.end()
})
})
})
it('should not get code if is not contract', (t) => {
const raw = {
nonce: '0x0',
balance: '0x03e7',
}
const account = new Account(raw)
const trie = new SecureTrie()
account.getCode(trie, function (err, code) {
t.equals(Buffer.compare(code!, Buffer.alloc(0)), 0)
t.end()
})
})
it('should set empty code', (t) => {
const raw = {
nonce: '0x0',
balance: '0x03e7',
}
const account = new Account(raw)
const trie = new SecureTrie()
const code = Buffer.alloc(0)
account.setCode(trie, code, function (err, codeHash) {
t.equals(Buffer.compare(codeHash, Buffer.alloc(0)), 0)
t.end()
})
})
})

tape('setStorage && getStorage', (tester) => {
const it = tester.test
it('should set and get storage', (t) => {
const raw = {
nonce: '0x0',
balance: '0x03e7',
stateRoot: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421',
codeHash: '0xb30fb32201fe0486606ad451e1a61e2ae1748343cd3d411ed992ffcc0774edd4',
}
const account = new Account(raw)
const trie = new SecureTrie()
const key = Buffer.from('0000000000000000000000000000000000000000', 'hex')
const value = Buffer.from('01', 'hex')

account.setStorage(trie, key, value, (err) => {
account.getStorage(trie, key, (err, valueRetrieved) => {
t.equals(Buffer.compare(value, valueRetrieved!), 0)
t.end()
})
})
})
})

tape('isEmpty', (tester) => {
const it = tester.test
it('should return true for an empty account', (t) => {
Expand Down
Loading

0 comments on commit 67a85b2

Please sign in to comment.