New definitions needed for the LES branch

This commit is contained in:
Zahary Karadjov 2018-10-16 02:45:51 +03:00
parent f32736b61d
commit 3edbb42fc6
4 changed files with 130 additions and 20 deletions

View File

@ -7,6 +7,7 @@ skipDirs = @["tests"]
requires "nim > 0.18.0",
"rlp",
"eth_trie",
"nimcrypto",
"ranges",
"stint",

View File

@ -1,9 +1,12 @@
import stint, nimcrypto, times, rlp, endians
export stint
import
endians, options, times,
stint, nimcrypto, rlp, eth_trie/[defs, db]
export
stint, read, append, KeccakHash
type
Hash256* = MDigest[256]
KeccakHash* = Hash256
EthTime* = Time
@ -23,6 +26,12 @@ type
## Type alias used for gas computation
# For reference - https://github.com/status-im/nimbus/issues/35#issuecomment-391726518
Account* = object
nonce*: AccountNonce
balance*: UInt256
storageRoot*: Hash256
codeHash*: Hash256
Transaction* = object
accountNonce*: AccountNonce
gasPrice*: GasInt
@ -34,6 +43,17 @@ type
R*, S*: UInt256
isContractCreation* {.rlpIgnore.}: bool
TransactionStatus* = enum
Unknown,
Queued,
Pending,
Included,
Error
TransactionStatusMsg* = object
status*: TransactionStatus
data*: Blob
BlockNumber* = UInt256
BlockHeader* = object
@ -104,10 +124,35 @@ type
maxResults*, skip*: uint
reverse*: bool
ProofRequest* = object
blockHash*: KeccakHash
accountKey*: Blob
key*: Blob
fromLevel*: uint
HeaderProofRequest* = object
chtNumber*: uint
blockNumber*: uint
fromLevel*: uint
ContractCodeRequest* = object
blockHash*: KeccakHash
key*: EthAddress
HelperTrieProofRequest* = object
subType*: uint
sectionIdx*: uint
key*: Blob
fromLevel*: uint
auxReq*: uint
AbstractChainDB* = ref object of RootRef
BlockHeaderRef* = ref BlockHeader
BlockBodyRef* = ref BlockBody
ReceiptRef* = ref Receipt
EthResourceRefs = BlockHeaderRef | BlockBodyRef | ReceiptRef
when BlockNumber is int64:
## The goal of these templates is to make it easier to switch
@ -137,6 +182,12 @@ proc toBlockNonce*(n: uint64): BlockNonce =
proc toUint*(n: BlockNonce): uint64 =
bigEndian64(addr result, unsafeAddr n[0])
proc newAccount*(nonce: AccountNonce = 0, balance: UInt256 = 0.u256): Account =
result.nonce = nonce
result.balance = balance
result.storageRoot = emptyRlpHash
result.codeHash = blankStringHash
#
# Rlp serialization:
#
@ -187,12 +238,6 @@ proc append*(rlpWriter: var RlpWriter, t: Transaction, a: EthAddress) {.inline.}
else:
rlpWriter.append(a)
proc read*(rlp: var Rlp, T: typedesc[MDigest]): T {.inline.} =
result.data = rlp.read(type(result.data))
proc append*(rlpWriter: var RlpWriter, a: MDigest) {.inline.} =
rlpWriter.append(a.data)
proc read*(rlp: var Rlp, T: typedesc[Time]): T {.inline.} =
result = fromUnix(rlp.read(int64))
@ -221,24 +266,68 @@ func blockHash*(h: BlockHeader): KeccakHash {.inline.} = rlpHash(h)
proc notImplemented =
assert false, "Method not impelemented"
template deref*(r: BlockHeaderRef | BlockBodyRef): auto =
r[]
template hasData*(b: Blob): bool = b.len > 0
template hasData*(r: EthResourceRefs): bool = r != nil
method genesisHash*(db: AbstractChainDb): KeccakHash {.base.} =
template deref*(b: Blob): auto = b
template deref*(o: Option): auto = o.get
template deref*(r: EthResourceRefs): auto = r[]
method genesisHash*(db: AbstractChainDB): KeccakHash {.base.} =
notImplemented()
method getBlockHeader*(db: AbstractChainDB, b: HashOrNum, output: var BlockHeader): bool =
notImplemented()
proc getBlockHeader*(db: AbstractChainDB, hash: KeccakHash): BlockHeaderRef =
new result
if not db.getBlockHeader(HashOrNum(isHash: true, hash: hash), result[]):
return nil
proc getBlockHeader*(db: AbstractChainDB, b: BlockNumber): BlockHeaderRef =
new result
if not db.getBlockHeader(HashOrNum(isHash: false, number: b), result[]):
return nil
method getBestBlockHeader*(self: AbstractChainDB): BlockHeader =
notImplemented()
method getSuccessorHeader*(db: AbstractChainDB, h: BlockHeader, output: var BlockHeader): bool =
notImplemented()
method getBlockBody*(db: AbstractChainDb, blockHash: KeccakHash): BlockBodyRef {.base.} =
method getBlockBody*(db: AbstractChainDB, blockHash: KeccakHash): BlockBodyRef {.base.} =
notImplemented()
method persistBlocks*(db: AbstractChainDb, headers: openarray[BlockHeader], bodies: openarray[BlockBody]) {.base.} =
method getReceipt*(db: AbstractChainDB, hash: KeccakHash): ReceiptRef =
notImplemented()
method getStateDb*(db: AbstractChainDB): TrieDatabaseRef =
notImplemented()
method getCodeByHash*(db: AbstractChainDB, hash: KeccakHash): Blob =
notImplemented()
method getSetting*(db: AbstractChainDb, key: string): Bytes =
notImplemented()
method setSetting*(db: AbstractChainDb, key: string, val: openarray[byte]) =
notImplemented()
method getHeaderProof*(db: AbstractChainDB, req: ProofRequest): Blob =
notImplemented()
method getProof*(db: AbstractChainDB, req: ProofRequest): Blob =
notImplemented()
method getHelperTrieProof*(db: AbstractChainDB, req: HelperTrieProofRequest): Blob =
notImplemented()
method getTransactionStatus*(db: AbstractChainDB, txHash: KeccakHash): TransactionStatusMsg =
notImplemented()
method addTransactions*(db: AbstractChainDB, transactions: openarray[Transaction]) =
notImplemented()
method persistBlocks*(db: AbstractChainDB, headers: openarray[BlockHeader], bodies: openarray[BlockBody]) {.base.} =
notImplemented()

View File

@ -0,0 +1,26 @@
import
eth_trie/[defs, db, hexary], rlp,
eth_types
proc getAccount*(db: TrieDatabaseRef,
rootHash: KeccakHash,
account: EthAddress): Account =
let trie = initSecureHexaryTrie(db, rootHash)
let data = trie.get(unnecessary_OpenArrayToRange account)
if data.len > 0:
result = rlp.decode(data, Account)
else:
result = newAccount()
proc getContractCode*(chain: AbstractChainDb, req: ContractCodeRequest): Blob =
let b = chain.getBlockHeader(req.blockHash)
if b.hasData:
let acc = getAccount(chain.getStateDb, b.stateRoot, req.key)
result = chain.getCodeByHash(acc.codeHash)
proc getStorageNode*(chain: AbstractChainDb, hash: KeccakHash): Blob =
let db = chain.getStateDb
return db.get(hash.data)
# let trie = initSecureHexaryTrie(db, emptyRlpHash) # TODO emptyRlpHash is not correct here
# return trie.get(unnecessary_OpenArrayToRange hash.data)

View File

@ -2,12 +2,6 @@ import nimcrypto, hashes, byteutils, eth_types
proc hash*(d: MDigest): Hash {.inline.} = hash(d.data)
proc toDigestAux(len: static[int], s: string): MDigest[len] =
hexToByteArray(s, result.data)
proc toDigest*(hexString: static[string]): auto =
toDigestAux(hexString.len div 2 * 8, hexString)
proc parseAddress*(hexString: string): EthAddress =
hexToPaddedByteArray[20](hexString)