Skip to content

Commit

Permalink
Merge branch 'master' into stateManager/integratePromises
Browse files Browse the repository at this point in the history
  • Loading branch information
evertonfraga authored Apr 21, 2020
2 parents 073c358 + 36fde16 commit 6b700bf
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 57 deletions.
8 changes: 8 additions & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
coverage:
status:
project:
default:
target: auto
threshold: 1%
base: auto

2 changes: 1 addition & 1 deletion packages/tx/examples/custom-chain-tx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const tx = new Transaction(
// Once we created the transaction using the custom Common object, we can use it as a normal tx.

// Here we sign it and validate its signature
const privateKey = new Buffer(
const privateKey = Buffer.from(
'e331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109',
'hex',
)
Expand Down
2 changes: 1 addition & 1 deletion packages/tx/examples/transactions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const tx = new Transaction({
})

// We sign the transaction with this private key
const privateKey = new Buffer(
const privateKey = Buffer.from(
'e331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109',
'hex',
)
Expand Down
24 changes: 12 additions & 12 deletions packages/tx/src/transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,57 +91,57 @@ export default class Transaction {
name: 'nonce',
length: 32,
allowLess: true,
default: new Buffer([]),
default: Buffer.from([]),
},
{
name: 'gasPrice',
length: 32,
allowLess: true,
default: new Buffer([]),
default: Buffer.from([]),
},
{
name: 'gasLimit',
alias: 'gas',
length: 32,
allowLess: true,
default: new Buffer([]),
default: Buffer.from([]),
},
{
name: 'to',
allowZero: true,
length: 20,
default: new Buffer([]),
default: Buffer.from([]),
},
{
name: 'value',
length: 32,
allowLess: true,
default: new Buffer([]),
default: Buffer.from([]),
},
{
name: 'data',
alias: 'input',
allowZero: true,
default: new Buffer([]),
default: Buffer.from([]),
},
{
name: 'v',
allowZero: true,
default: new Buffer([]),
default: Buffer.from([]),
},
{
name: 'r',
length: 32,
allowZero: true,
allowLess: true,
default: new Buffer([]),
default: Buffer.from([]),
},
{
name: 's',
length: 32,
allowZero: true,
allowLess: true,
default: new Buffer([]),
default: Buffer.from([]),
},
]

Expand Down Expand Up @@ -262,9 +262,9 @@ export default class Transaction {
sign(privateKey: Buffer) {
// We clear any previous signature before signing it. Otherwise, _implementsEIP155's can give
// different results if this tx was already signed.
this.v = new Buffer([])
this.s = new Buffer([])
this.r = new Buffer([])
this.v = Buffer.from([])
this.s = Buffer.from([])
this.r = Buffer.from([])

const msgHash = this.hash(false)
const sig = ecsign(msgHash, privateKey)
Expand Down
18 changes: 9 additions & 9 deletions packages/tx/test/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,15 @@ tape('[Transaction]: Basic functions', function(t) {
const tx = new Transaction(txFixtures[3].raw)
st.deepEqual(
tx.hash(),
new Buffer('375a8983c9fc56d7cfd118254a80a8d7403d590a6c9e105532b67aca1efb97aa', 'hex'),
Buffer.from('375a8983c9fc56d7cfd118254a80a8d7403d590a6c9e105532b67aca1efb97aa', 'hex'),
)
st.deepEqual(
tx.hash(false),
new Buffer('61e1ec33764304dddb55348e7883d4437426f44ab3ef65e6da1e025734c03ff0', 'hex'),
Buffer.from('61e1ec33764304dddb55348e7883d4437426f44ab3ef65e6da1e025734c03ff0', 'hex'),
)
st.deepEqual(
tx.hash(true),
new Buffer('375a8983c9fc56d7cfd118254a80a8d7403d590a6c9e105532b67aca1efb97aa', 'hex'),
Buffer.from('375a8983c9fc56d7cfd118254a80a8d7403d590a6c9e105532b67aca1efb97aa', 'hex'),
)
st.end()
})
Expand Down Expand Up @@ -106,7 +106,7 @@ tape('[Transaction]: Basic functions', function(t) {
t.test('should sign tx', function(st) {
transactions.forEach(function(tx, i) {
if (txFixtures[i].privateKey) {
const privKey = new Buffer(txFixtures[i].privateKey, 'hex')
const privKey = Buffer.from(txFixtures[i].privateKey, 'hex')
tx.sign(privKey)
}
})
Expand All @@ -127,7 +127,7 @@ tape('[Transaction]: Basic functions', function(t) {
if (txFixtures[i].privateKey) {
st.equals(
tx.getSenderPublicKey().toString('hex'),
privateToPublic(new Buffer(txFixtures[i].privateKey, 'hex')).toString('hex'),
privateToPublic(Buffer.from(txFixtures[i].privateKey, 'hex')).toString('hex'),
)
}
})
Expand Down Expand Up @@ -280,7 +280,7 @@ tape('[Transaction]: Basic functions', function(t) {
t.test('sign tx with chainId specified in params', function(st) {
const tx = new Transaction({}, { chain: 42 })
st.equal(tx.getChainId(), 42)
const privKey = new Buffer(txFixtures[0].privateKey, 'hex')
const privKey = Buffer.from(txFixtures[0].privateKey, 'hex')
tx.sign(privKey)
const serialized = tx.serialize()
const reTx = new Transaction(serialized, { chain: 42 })
Expand All @@ -294,7 +294,7 @@ tape('[Transaction]: Basic functions', function(t) {
) {
const tx = new Transaction({}, { chain: 42 })
st.equal(tx.getChainId(), 42)
const privKey = new Buffer(txFixtures[0].privateKey, 'hex')
const privKey = Buffer.from(txFixtures[0].privateKey, 'hex')
tx.sign(privKey)
const serialized = tx.serialize()
st.throws(() => new Transaction(serialized))
Expand Down Expand Up @@ -322,7 +322,7 @@ tape('[Transaction]: Basic functions', function(t) {
st,
) {
const tx = new Transaction({}, { chain: 42 })
const privKey = new Buffer(txFixtures[0].privateKey, 'hex')
const privKey = Buffer.from(txFixtures[0].privateKey, 'hex')
tx.sign(privKey)

st.throws(() => (tx.v = toBuffer(1)))
Expand All @@ -337,7 +337,7 @@ tape('[Transaction]: Basic functions', function(t) {
txFixtures.slice(0, 3).forEach(function(txData) {
const tx = new Transaction(txData.raw.slice(0, 6), { chain: 1 })

const privKey = new Buffer(txData.privateKey, 'hex')
const privKey = Buffer.from(txData.privateKey, 'hex')
tx.sign(privKey)

st.equal(
Expand Down
39 changes: 13 additions & 26 deletions packages/vm/lib/evm/interpreter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,11 @@ export interface InterpreterStep {
address: Buffer
memory: number[]
memoryWordCount: BN
opcode: Opcode
opcode: {
name: string
fee: number
isAsync: boolean
}
account: Account
codeAddress: Buffer
}
Expand Down Expand Up @@ -146,39 +150,22 @@ export default class Interpreter {
/**
* Get info for an opcode from VM's list of opcodes.
*/
lookupOpInfo(op: number, full: boolean = false): Opcode {
const opcode = this._vm._opcodes[op]
? this._vm._opcodes[op]
: { name: 'INVALID', fee: 0, isAsync: false }

if (full) {
let name = opcode.name
if (name === 'LOG') {
name += op - 0xa0
}

if (name === 'PUSH') {
name += op - 0x5f
}

if (name === 'DUP') {
name += op - 0x7f
}

if (name === 'SWAP') {
name += op - 0x8f
}
return { ...opcode, ...{ name } }
}
lookupOpInfo(op: number): Opcode {
const opcode = this._vm._opcodes[op] ? this._vm._opcodes[op] : this._vm._opcodes[0xfe]

return opcode
}

async _runStepHook(): Promise<void> {
const opcode = this.lookupOpInfo(this._runState.opCode)
const eventObj: InterpreterStep = {
pc: this._runState.programCounter,
gasLeft: this._eei.getGasLeft(),
opcode: this.lookupOpInfo(this._runState.opCode, true),
opcode: {
name: opcode.fullName,
fee: opcode.fee,
isAsync: opcode.isAsync,
},
stack: this._runState.stack._store,
depth: this._eei._env.depth,
address: this._eei._env.address,
Expand Down
93 changes: 85 additions & 8 deletions packages/vm/lib/evm/opcodes.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,41 @@
import Common from 'ethereumjs-common'

export interface Opcode {
name: string
fee: number
isAsync: boolean
export class Opcode {
readonly code: number
readonly name: string
readonly fullName: string
readonly fee: number
readonly isAsync: boolean

constructor({
code,
name,
fullName,
fee,
isAsync,
}: {
code: number
name: string
fullName: string
fee: number
isAsync: boolean
}) {
this.code = code
this.name = name
this.fullName = fullName
this.fee = fee
this.isAsync = isAsync

// Opcode isn't subject to change, thus all futher modifications are prevented.
Object.freeze(this)
}
}

export interface OpcodeList {
[code: number]: Opcode
}

const opcodes: OpcodeList = {
const opcodes: OpcodeList = createOpcodes({
// 0x0 range - arithmetic ops
// name, baseCost, async
0x00: { name: 'STOP', fee: 0, isAsync: false },
Expand Down Expand Up @@ -172,17 +197,69 @@ const opcodes: OpcodeList = {
// '0x70', range - other
0xfe: { name: 'INVALID', fee: 0, isAsync: false },
0xff: { name: 'SELFDESTRUCT', fee: 5000, isAsync: true },
}
})

const istanbulOpcodes: OpcodeList = {
const istanbulOpcodes: OpcodeList = createOpcodes({
0x31: { name: 'BALANCE', fee: 700, isAsync: true },
0x3f: { name: 'EXTCODEHASH', fee: 700, isAsync: true },
0x46: { name: 'CHAINID', fee: 2, isAsync: false },
0x47: { name: 'SELFBALANCE', fee: 5, isAsync: false },
0x54: { name: 'SLOAD', fee: 800, isAsync: true },
})

/**
* Convert basic opcode info dictonary into complete OpcodeList instance.
*
* @param opcodes {Object} Receive basic opcodes info dictionary.
* @returns {OpcodeList} Complete Opcode list
*/
function createOpcodes(opcodes: {
[key: string]: { name: string; fee: number; isAsync: boolean }
}): OpcodeList {
const result: OpcodeList = {}
for (const [key, value] of Object.entries(opcodes)) {
const code = parseInt(key, 10)
result[<any>key] = new Opcode({
code,
fullName: getFullname(code, value.name),
...value,
})
}
return result
}

/**
* Get full opcode name from its name and code.
*
* @param code {number} Integer code of opcode.
* @param name {string} Short name of the opcode.
* @returns {string} Full opcode name
*/
function getFullname(code: number, name: string): string {
switch (name) {
case 'LOG':
name += code - 0xa0
break
case 'PUSH':
name += code - 0x5f
break
case 'DUP':
name += code - 0x7f
break
case 'SWAP':
name += code - 0x8f
break
}
return name
}

export function getOpcodesForHF(common: Common) {
/**
* Get suitable opcodes for the required hardfork.
*
* @param common {Common} Ethereumjs Common metadaata object.
* @returns {OpcodeList} Opcodes dictionary object.
*/
export function getOpcodesForHF(common: Common): OpcodeList {
if (common.gteHardfork('istanbul')) {
return { ...opcodes, ...istanbulOpcodes }
} else {
Expand Down

0 comments on commit 6b700bf

Please sign in to comment.