mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-01-12 13:24:21 +00:00
Work on text fitures and decompiling bytecode
This commit is contained in:
parent
925eb627a5
commit
0d31382e3d
7
examples/a.nim
Normal file
7
examples/a.nim
Normal file
@ -0,0 +1,7 @@
|
||||
import vm/code_stream, opcode_values
|
||||
|
||||
var c = newCodeStream("\x60\x00\x60\x00\x60\x00\x60\x00\x67\x06\xf0\x5b\x59\xd3\xb2\x00\x00\x33\x60\xc8\x5a\x03\xf1")
|
||||
|
||||
let opcodes = c.decompile()
|
||||
for op in opcodes:
|
||||
echo op[0], " ", op[1], " ", op[2]
|
1
examples/nim.cfg
Normal file
1
examples/nim.cfg
Normal file
@ -0,0 +1 @@
|
||||
-p:"../src"
|
@ -1,5 +1,5 @@
|
||||
import
|
||||
logging, constants, utils/header
|
||||
logging, constants, utils / header, ttmath
|
||||
|
||||
type
|
||||
CountableList*[T] = ref object
|
||||
|
@ -1,6 +1,6 @@
|
||||
import
|
||||
tables,
|
||||
logging, constants, errors, validation, utils / [hexadecimal]
|
||||
tables, ttmath,
|
||||
logging, constants, errors, validation, utils / hexadecimal, vm / base, db / db_chain
|
||||
|
||||
type
|
||||
BlockHeader* = ref object
|
||||
@ -18,6 +18,9 @@ type
|
||||
importBlock*: bool
|
||||
validateBlock*: bool
|
||||
db*: BaseChainDB
|
||||
fundedAddress*: string
|
||||
fundedAddressInitialBalance*: int
|
||||
fundedAddressPrivateKey*: string
|
||||
|
||||
GenesisParams* = ref object
|
||||
blockNumber*: Int256
|
||||
@ -25,11 +28,11 @@ type
|
||||
gasLimit*: Int256
|
||||
parentHash*: string
|
||||
coinbase*: string
|
||||
nonce: string
|
||||
mixHash: string
|
||||
extraData: string
|
||||
timestamp: int,
|
||||
stateRoot: string
|
||||
nonce*: string
|
||||
mixHash*: string
|
||||
extraData*: string
|
||||
timestamp*: int
|
||||
stateRoot*: string
|
||||
|
||||
FundedAddress* = ref object
|
||||
balance*: Int256
|
||||
@ -40,6 +43,8 @@ type
|
||||
proc configureChain*(name: string, blockNumber: Int256, vm: VM, importBlock: bool = true, validateBlock: bool = true): Chain =
|
||||
new(result)
|
||||
result.vmsByRange = @[(blockNumber: blockNumber, vm: vm)]
|
||||
result.importBlock = importBlock
|
||||
result.validateBlock = validateBlock
|
||||
|
||||
proc fromGenesis*(
|
||||
chain: Chain,
|
||||
@ -48,13 +53,18 @@ proc fromGenesis*(
|
||||
genesisState: Table[string, FundedAddress]): Chain =
|
||||
## Initialize the Chain from a genesis state
|
||||
var stateDB = chaindb.getStateDB(BLANK_ROOT_HASH)
|
||||
for account, accountData in genesisState:
|
||||
stateDB.setBalance(account, accountData.balance)
|
||||
stateDB.setNonce(account, accountData.nonce)
|
||||
stateDB.setCode(account, accountData.code)
|
||||
|
||||
# TODO
|
||||
# for account, accountData in genesisState:
|
||||
# stateDB.setBalance(account, accountData.balance)
|
||||
# stateDB.setNonce(account, accountData.nonce)
|
||||
# stateDB.setCode(account, accountData.code)
|
||||
|
||||
new(result)
|
||||
result.db = chainDB
|
||||
result.header = BlockHeader()
|
||||
result.logger = logging.getLogger("evm.chain.chain.Chain")
|
||||
chainDB.persistBlockToDB(result.getBlock())
|
||||
result.importBlock = chain.importBlock
|
||||
result.validateBlock = chain.validateBlock
|
||||
result.vmsByRange = chain.vmsByRange
|
||||
# TODO
|
||||
# chainDB.persistBlockToDB(result.getBlock)
|
||||
|
@ -191,7 +191,7 @@ let
|
||||
GENESIS_COINBASE* = ZERO_ADDRESS
|
||||
GENESIS_NONCE* = "\x00\x00\x00\x00\x00\x00\x00B"
|
||||
GENESIS_MIX_HASH* = ZERO_HASH32
|
||||
GENESIS_EXTRA_DATA = ""
|
||||
GENESIS_EXTRA_DATA* = ""
|
||||
|
||||
EMPTYSHA3 = "\xc5\xd2F\x01\x86\xf7#<\x92~}\xb2\xdc\xc7\x03\xc0\xe5\x00\xb6S\xca\x82';{\xfa\xd8\x04]\x85\xa4p"
|
||||
BLANK_ROOT_HASH* = "V\xe8\x1f\x17\x1b\xccU\xa6\xff\x83E\xe6\x92\xc0\xf8n[H\xe0\x1b\x99l\xad\xc0\x01b/\xb5\xe3c\xb4!"
|
||||
|
23
src/db/backends/memory_backend.nim
Normal file
23
src/db/backends/memory_backend.nim
Normal file
@ -0,0 +1,23 @@
|
||||
import tables, ttmath
|
||||
|
||||
type
|
||||
MemoryDB* = ref object
|
||||
kvStore*: Table[string, Int256]
|
||||
|
||||
proc newMemoryDB*(kvStore: Table[string, Int256]): MemoryDB =
|
||||
MemoryDB(kvStore: kvStore)
|
||||
|
||||
proc newMemoryDB*: MemoryDB =
|
||||
MemoryDB(kvStore: initTable[string, Int256]())
|
||||
|
||||
proc get*(db: MemoryDB, key: string): Int256 =
|
||||
db.kvStore[key]
|
||||
|
||||
proc set*(db: var MemoryDB, key: string, value: Int256) =
|
||||
db.kvStore[key] = value
|
||||
|
||||
proc exists*(db: MemoryDB, key: string): bool =
|
||||
db.kvStore.hasKey(key)
|
||||
|
||||
proc delete*(db: var MemoryDB, key: string) =
|
||||
db.kvStore.del(key)
|
@ -1,12 +1,15 @@
|
||||
import strformat, tables, ttmath, state_db, backends / memory_backend
|
||||
|
||||
type
|
||||
BaseChainDB* = ref object
|
||||
db*: MemoryDB
|
||||
# TODO db*: JournalDB
|
||||
|
||||
# proc makeBaseChainDB*(db: MemoryDB): BaseChainDB =
|
||||
# result.db = JournalDB(db)
|
||||
proc newBaseChainDB*(db: MemoryDB): BaseChainDB =
|
||||
result.db = db
|
||||
|
||||
# proc exists*(self: BaseChainDB; key: cstring): bool =
|
||||
# return self.db.exists(key)
|
||||
proc exists*(self: BaseChainDB; key: string): bool =
|
||||
return self.db.exists(key)
|
||||
|
||||
# proc getCanonicalHead*(self: BaseChainDB): BlockHeader =
|
||||
# if notself.exists(CANONICALHEADHASHDBKEY):
|
||||
@ -145,7 +148,7 @@ type
|
||||
# proc clear*(self: BaseChainDB): void =
|
||||
# self.db.clear()
|
||||
|
||||
# proc getStateDb*(self: BaseChainDB; stateRoot: cstring; readOnly: bool): AccountStateDB =
|
||||
# return AccountStateDB()
|
||||
method getStateDb*(self: BaseChainDB; stateRoot: string; readOnly: bool = false): AccountStateDB =
|
||||
return newAccountStateDB(initTable[string, Int256]())
|
||||
|
||||
# var CANONICALHEADHASHDBKEY = cstring"v1:canonical_head_hash"
|
@ -1,5 +1,5 @@
|
||||
import
|
||||
../logging, ../constants, ../errors, ../transaction, ../computation, "../block", ../vm_state, ../vm_state_transactions, ../db/chain, ../utils/header
|
||||
../logging, ../constants, ../errors, ../transaction, ../computation, "../block", ../vm_state, ../vm_state_transactions, ../db/db_chain, ../utils/header
|
||||
|
||||
type
|
||||
VM* = ref object of RootObj
|
||||
|
@ -94,3 +94,19 @@ proc isValidOpcode*(c: var CodeStream, position: int): bool =
|
||||
return false
|
||||
else:
|
||||
return true
|
||||
|
||||
proc decompile*(original: CodeStream): seq[(int, Op, string)] =
|
||||
# behave as https://etherscan.io/opcode-tool
|
||||
# TODO
|
||||
result = @[]
|
||||
var c = newCodeStream(original.bytes)
|
||||
while true:
|
||||
var op = c.next
|
||||
if op >= PUSH1 and op <= PUSH32:
|
||||
let bytes = c.read(op.int - 95)
|
||||
result.add((c.pc - 1, op, "0x" & bytes.mapIt($(it.BiggestInt.toHex(2))).join("")))
|
||||
elif op != Op.Stop:
|
||||
result.add((c.pc - 1, op, ""))
|
||||
else:
|
||||
result.add((-1, Op.STOP, ""))
|
||||
break
|
||||
|
@ -1,6 +1,6 @@
|
||||
import
|
||||
strformat,
|
||||
constants, errors, vm_state, transaction, utils/header
|
||||
constants, errors, ttmath, vm_state, transaction, utils/header
|
||||
|
||||
proc validateFrontierTransaction*(vmState: BaseVmState, transaction: BaseTransaction) =
|
||||
let gasCost = transaction.gas * transaction.gasPrice
|
||||
@ -9,7 +9,7 @@ proc validateFrontierTransaction*(vmState: BaseVmState, transaction: BaseTransac
|
||||
# senderBalance = db.getBalance(transaction.sender)
|
||||
senderBalance = gasCost # TODO
|
||||
if senderBalance < gasCost:
|
||||
raise newException(ValidationError, %"Sender account balance cannot afford txn gas: {transaction.sender}")
|
||||
raise newException(ValidationError, &"Sender account balance cannot afford txn gas: {transaction.sender}")
|
||||
|
||||
let totalCost = transaction.value + gasCost
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import
|
||||
logging, constants, errors, vm_state, utils/header, db/chain
|
||||
logging, constants, errors, vm_state, utils/header, db/db_chain
|
||||
|
||||
type
|
||||
FrontierVMState* = object of BaseVMState
|
||||
|
@ -1,5 +1,5 @@
|
||||
import
|
||||
logging, constants, errors, "block", vm / [base, stack], db / chain, utils / header,
|
||||
logging, constants, errors, ttmath, "block", vm / [base, stack], db / db_chain, utils / header,
|
||||
frontier_block, frontier_vm_state, frontier_validation
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import
|
||||
strformat, tables,
|
||||
logging, constants, ttmath, errors, transaction, db/chain, utils/state, utils/header
|
||||
logging, constants, ttmath, errors, transaction, db/db_chain, utils/state, utils/header
|
||||
|
||||
type
|
||||
BaseVMState* = ref object of RootObj
|
||||
|
@ -1,6 +1,6 @@
|
||||
import
|
||||
strformat, tables,
|
||||
logging, constants, errors, computation, transaction, vm_state, "block", db/chain, utils/state, utils/header
|
||||
logging, constants, errors, computation, transaction, vm_state, "block", db / db_chain, utils / [state, header]
|
||||
|
||||
method executeTransaction(vmState: var BaseVMState, transaction: BaseTransaction): (BaseComputation, Header) =
|
||||
# Execute the transaction in the vm
|
||||
|
28
tests/fixtures.nim
Normal file
28
tests/fixtures.nim
Normal file
@ -0,0 +1,28 @@
|
||||
import unittest, strformat, tables, constants, chain, ttmath, vm / forks / frontier / vm, utils / [header, address], db / db_chain, db / backends / memory_backend
|
||||
|
||||
proc chainWithoutBlockValidation: Chain =
|
||||
result = configureChain("TestChain", GENESIS_BLOCK_NUMBER, newFrontierVM(Header(), newBaseChainDB(newMemoryDB())), false, false)
|
||||
let privateKey = "0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8" # TODO privateKey(decodeHex("0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8"))
|
||||
let fundedAddr = privateKey # privateKey.publicKey.toCanonicalAddress
|
||||
let initialBalance = 100_000_000
|
||||
let genesisParams = GenesisParams(
|
||||
blockNumber: GENESIS_BLOCK_NUMBER,
|
||||
difficulty: GENESIS_DIFFICULTY,
|
||||
gasLimit: GENESIS_GAS_LIMIT,
|
||||
parentHash: GENESIS_PARENT_HASH,
|
||||
coinbase: GENESIS_COINBASE,
|
||||
nonce: GENESIS_NONCE,
|
||||
mixHash: GENESIS_MIX_HASH,
|
||||
extraData: GENESIS_EXTRA_DATA,
|
||||
timestamp: 1501851927,
|
||||
stateRoot: "0x9d354f9b5ba851a35eced279ef377111387197581429cfcc7f744ef89a30b5d4") #.decodeHex)
|
||||
let genesisState = {"fundedAddr": FundedAddress(balance: initialBalance.int256, nonce: 0, code: "")}.toTable()
|
||||
result = fromGenesis(
|
||||
result,
|
||||
newBaseChainDB(newMemoryDB()),
|
||||
genesisParams,
|
||||
genesisState)
|
||||
result.fundedAddress = fundedAddr
|
||||
result.fundedAddressInitialBalance = initialBalance
|
||||
result.fundedAddressPrivateKey = privateKey
|
||||
|
Loading…
x
Reference in New Issue
Block a user