nimbus-eth1/tests/test_txpool/sign_helper.nim

102 lines
2.9 KiB
Nim

# Nimbus
# Copyright (c) 2022-2024 Status Research & Development GmbH
# Licensed under either of
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
# http://www.apache.org/licenses/LICENSE-2.0)
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or
# http://opensource.org/licenses/MIT)
# at your option. This file may not be copied, modified, or distributed except
# according to those terms.
import
../../nimbus/constants,
../../nimbus/utils/ec_recover,
../../nimbus/core/tx_pool/tx_item,
eth/[common, common/transaction, keys],
results,
stint
const
# example from clique, signer: 658bdf435d810c91414ec09147daa6db62406379
prvKey = "9c647b8b7c4e7c3490668fb6c11473619db80c93704c70893d3813af4090c39c"
proc signature(tx: Transaction; key: PrivateKey): (uint64,UInt256,UInt256) =
let
hashData = tx.txHashNoSignature.data
signature = key.sign(SkMessage(hashData)).toRaw
v = signature[64].uint64
result[1] = UInt256.fromBytesBE(signature[0..31])
result[2] = UInt256.fromBytesBE(signature[32..63])
if tx.txType == TxLegacy:
if tx.V >= EIP155_CHAIN_ID_OFFSET:
# just a guess which does not always work .. see `txModPair()`
# see https://eips.ethereum.org/EIPS/eip-155
result[0] = (tx.V and not 1'u64) or (not v and 1'u64)
else:
result[0] = 27 + v
else:
# currently unsupported, will skip this one .. see `txModPair()`
result[0] = 0'u64
proc sign(tx: Transaction; key: PrivateKey): Transaction =
let (V,R,S) = tx.signature(key)
result = tx
result.V = V
result.R = R
result.S = S
proc sign(header: BlockHeader; key: PrivateKey): BlockHeader =
let
hashData = header.blockHash.data
signature = key.sign(SkMessage(hashData)).toRaw
result = header
result.extraData.add signature
# ------------
let
prvTestKey* = PrivateKey.fromHex(prvKey).value
pubTestKey* = prvTestKey.toPublicKey
testAddress* = pubTestKey.toCanonicalAddress
proc txModPair*(item: TxItemRef; nonce: int; priceBump: int):
(TxItemRef,Transaction,Transaction) =
## Produce pair of modified txs, might fail => so try another one
var tx0 = item.tx
tx0.nonce = nonce.AccountNonce
var tx1 = tx0
tx1.gasPrice = (tx0.gasPrice * (100 + priceBump) + 99) div 100
let
tx0Signed = tx0.sign(prvTestKey)
tx1Signed = tx1.sign(prvTestKey)
block:
let rc = tx0Signed.ecRecover
if rc.isErr or rc.value != testAddress:
return
block:
let rc = tx1Signed.ecRecover
if rc.isErr or rc.value != testAddress:
return
(item,tx0Signed,tx1Signed)
proc testKeySign*(header: BlockHeader): BlockHeader =
## Sign the header and embed the signature in extra data
header.sign(prvTestKey)
proc signerFunc*(signer: EthAddress, msg: openArray[byte]):
Result[array[RawSignatureSize, byte], cstring] {.gcsafe.} =
doAssert(signer == testAddress)
let
data = keccakHash(msg)
rawSign = sign(prvTestKey, SkMessage(data.data)).toRaw
ok(rawSign)
# End