Fix loading blocks into blockchain

pull/5370/head
ioedeveloper 1 year ago
parent 8fd6b85572
commit a002c7ce32
  1. 6
      apps/remix-ide/src/blockchain/providers/vm.ts
  2. 21
      libs/remix-lib/src/execution/txRunnerVM.ts
  3. 4
      libs/remix-simulator/src/methods/transactions.ts
  4. 4
      libs/remix-simulator/src/provider.ts
  5. 39
      libs/remix-simulator/src/vm-context.ts

@ -3,7 +3,6 @@ import { fromWei, toBigInt } from 'web3-utils'
import { privateToAddress, hashPersonalMessage, isHexString } from '@ethereumjs/util'
import { extend, JSONRPCRequestPayload, JSONRPCResponseCallback } from '@remix-project/remix-simulator'
import {toBuffer} from '@ethereumjs/util'
import { Block } from '@ethereumjs/block'
import { ExecutionContext } from '../execution-context'
export class VMProvider {
@ -79,8 +78,7 @@ export class VMProvider {
if (stringifiedState) {
try {
const blockchainState = JSON.parse(stringifiedState)
const blocks: Block[] = blockchainState.blocks.map(block => Block.fromRLPSerializedBlock(toBuffer(block)))
const blockNumber = toBigInt(blockchainState.latestBlockNumber).toString(10)
const blockNumber = parseInt(blockchainState.latestBlockNumber, 16)
const stateDb = {
root: toBuffer(blockchainState.root),
db: new Map(Object.entries(blockchainState.db))
@ -92,7 +90,7 @@ export class VMProvider {
nodeUrl: provider?.options['nodeUrl'],
blockNumber,
stateDb,
blocks
blocks: blockchainState.blocks
})
} catch (e) {
console.error(e)

@ -24,24 +24,23 @@ export class TxRunnerVM {
pendingTxs
vmaccounts
queusTxs
blocks
blocks: Buffer[]
logsManager
commonContext
blockParentHash
nextNonceForCall: number
getVMObject: () => any
constructor (vmaccounts, api, getVMObject, blockNumber) {
constructor (vmaccounts, api, getVMObject, blocks: Buffer[] = []) {
this.event = new EventManager()
this.logsManager = new LogsManager()
// has a default for now for backwards compatibility
this.getVMObject = getVMObject
this.commonContext = this.getVMObject().common
this.blockNumber = blockNumber || 0 // TODO: this should be set to the fetched block number count
this.blockNumber = Array.isArray(blocks) ? blocks.length : 0 // TODO: this should be set to the fetched block number count
this.pendingTxs = {}
this.vmaccounts = vmaccounts
this.queusTxs = []
this.blocks = []
/*
txHash is generated using the nonce,
in order to have unique transaction hash, we need to keep using different nonce (in case of a call)
@ -51,7 +50,15 @@ export class TxRunnerVM {
this.nextNonceForCall = 0
const vm = this.getVMObject().vm
this.blockParentHash = vm.blockchain.genesisBlock.hash()
if (Array.isArray(blocks) && (blocks || []).length > 0) {
const block = Block.fromRLPSerializedBlock(blocks[blocks.length - 1], { common: this.commonContext })
this.blockParentHash = block.hash()
this.blocks = blocks
} else {
this.blockParentHash = vm.blockchain.genesisBlock.hash()
this.blocks = [vm.blockchain.genesisBlock.serialize()]
}
}
execute (args: InternalTransaction, confirmationCb, gasEstimationForceSend, promptCb, callback: VMExecutionCallBack) {
@ -107,7 +114,7 @@ export class TxRunnerVM {
const difficulties = [69762765929000, 70762765929000, 71762765929000]
const difficulty = this.commonContext.consensusType() === ConsensusType.ProofOfStake ? 0 : difficulties[this.blockNumber % difficulties.length]
const blocknumber = this.blockNumber + 1
const blocknumber = this.blocks.length
const block = Block.fromBlockData({
header: {
timestamp: new Date().getTime() / 1000 | 0,
@ -122,7 +129,7 @@ export class TxRunnerVM {
}, { common: this.commonContext, hardforkByBlockNumber: false, hardforkByTTD: undefined })
if (!useCall) {
this.blockNumber = this.blockNumber + 1
this.blockNumber = blocknumber
this.blockParentHash = block.hash()
this.runBlockInVm(tx, block, (err, result) => {
if (!err) {

@ -32,7 +32,7 @@ export class Transactions {
this.tags = {}
}
init (accounts, blockNumber) {
init (accounts, blocksData: Buffer[]) {
this.accounts = accounts
const api = {
logMessage: (msg) => {
@ -55,7 +55,7 @@ export class Transactions {
}
}
this.txRunnerVMInstance = new TxRunnerVM(accounts, api, _ => this.vmContext.vmObject(), blockNumber)
this.txRunnerVMInstance = new TxRunnerVM(accounts, api, _ => this.vmContext.vmObject(), blocksData)
this.txRunnerInstance = new TxRunner(this.txRunnerVMInstance, {})
this.txRunnerInstance.vmaccounts = accounts
}

@ -39,7 +39,7 @@ export type ProviderOptions = {
blockNumber: number | 'latest',
stateDb?: State,
logDetails?: boolean
blocks?: Block[]
blocks?: string[]
}
export class Provider {
@ -75,7 +75,7 @@ export class Provider {
this.pendingRequests = []
await this.vmContext.init()
await this.Accounts.resetAccounts()
this.Transactions.init(this.Accounts.accounts, this.vmContext.blockNumber, this.vmContext.blocks)
this.Transactions.init(this.Accounts.accounts, this.vmContext.serializedBlocks)
this.initialized = true
if (this.pendingRequests.length > 0) {
this.pendingRequests.map((req) => {

@ -66,7 +66,7 @@ class StateManagerCommonStorageDump extends DefaultStateManager {
stateDb: State
constructor (opts: DefaultStateManagerOpts = {}, stateDb?: State) {
const db = new RemixMapDb(stateDb ? stateDb.db: null)
const trie = new Trie({ useKeyHashing: true, db, root: stateDb ? stateDb.root : null })
const trie = new Trie({ useKeyHashing: true, db, useRootPersistence: true})
opts = { trie, ...opts }
super(opts)
this.stateDb = stateDb
@ -332,9 +332,10 @@ export class VMContext {
nodeUrl: string
blockNumber: number | 'latest'
stateDb: State
blocksData: Block[]
rawBlocks: string[]
serializedBlocks: Buffer[]
constructor (fork?: string, nodeUrl?: string, blockNumber?: number | 'latest', stateDb?: State, blocksData?: Block[]) {
constructor (fork?: string, nodeUrl?: string, blockNumber?: number | 'latest', stateDb?: State, blocksData?: string[]) {
this.blockGasLimitDefault = 4300000
this.blockGasLimit = this.blockGasLimitDefault
this.currentFork = fork || 'merge'
@ -347,7 +348,8 @@ export class VMContext {
this.txByHash = {}
this.exeResults = {}
this.logsManager = new LogsManager()
this.blocksData = blocksData
this.rawBlocks = blocksData
this.serializedBlocks = []
}
async init () {
@ -380,7 +382,13 @@ export class VMContext {
const difficulty = consensusType === ConsensusType.ProofOfStake ? 0 : 69762765929000
const common = new VMCommon({ chain: 'mainnet', hardfork })
const genesisBlock: Block = Block.fromBlockData({
const blocks = (this.rawBlocks || []).map(block => {
const serializedBlock = toBuffer(block)
this.serializedBlocks.push(serializedBlock)
return Block.fromRLPSerializedBlock(serializedBlock, { common })
})
const genesisBlock: Block = blocks.length > 0 && (blocks[0] || {}).isGenesis ? blocks[0] : Block.fromBlockData({
header: {
timestamp: (new Date().getTime() / 1000 | 0),
number: 0,
@ -389,13 +397,7 @@ export class VMContext {
gasLimit: 8000000
}
}, { common, hardforkByBlockNumber: false, hardforkByTTD: undefined })
let blockchain
if (Array.isArray(this.blocksData) && this.blocksData.length > 0) {
blockchain = await Blockchain.fromBlocksData(this.blocksData, { common, validateBlocks: false, validateConsensus: false })
} else {
blockchain = await Blockchain.create({ common, validateBlocks: false, validateConsensus: false, genesisBlock })
}
const blockchain = await Blockchain.create({ common, validateBlocks: false, validateConsensus: false, genesisBlock })
const eei = new EEI(stateManager, common, blockchain)
const evm = new EVM({ common, eei, allowUnlimitedContractSize: true })
@ -407,13 +409,17 @@ export class VMContext {
blockchain,
evm
})
// VmProxy and VMContext are very intricated.
// VmProxy is used to track the EVM execution (to listen on opcode execution, in order for instance to generate the VM trace)
const web3vm = new VmProxy(this)
web3vm.setVM(vm)
this.addBlock(genesisBlock, true)
return { vm, web3vm, stateManager, common }
if (blocks.length > 0) blocks.splice(0, 1)
blocks.forEach(block => {
blockchain.putBlock(block)
this.addBlock(block, false, false, web3vm)
})
return { vm, web3vm, stateManager, common, blocks }
}
getCurrentFork () {
@ -432,7 +438,7 @@ export class VMContext {
return this.currentVm
}
addBlock (block: Block, genesis?: boolean, isCall?: boolean) {
addBlock (block: Block, genesis?: boolean, isCall?: boolean, web3vm?: VmProxy) {
let blockNumber = bigIntToHex(block.header.number)
if (blockNumber === '0x') {
blockNumber = '0x0'
@ -442,7 +448,8 @@ export class VMContext {
this.blocks[blockNumber] = block
this.latestBlockNumber = blockNumber
if (!isCall && !genesis) this.logsManager.checkBlock(blockNumber, block, this.web3())
if (!isCall && !genesis && web3vm) this.logsManager.checkBlock(blockNumber, block, web3vm)
if (!isCall && !genesis && !web3vm) this.logsManager.checkBlock(blockNumber, block, this.web3())
}
trackTx (txHash, block, tx) {

Loading…
Cancel
Save