mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-19 21:31:37 +00:00
Minor Changes added
This commit is contained in:
parent
6d1685646f
commit
22732d57fb
4 changed files with 319 additions and 39 deletions
|
|
@ -44,10 +44,17 @@ import (
|
|||
"github.com/ethereum/go-ethereum/rpc"
|
||||
"github.com/syndtr/goleveldb/leveldb"
|
||||
"github.com/syndtr/goleveldb/leveldb/util"
|
||||
contractValidator "github.com/ethereum/go-ethereum/contracts/validator/contract"
|
||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultGasPrice = 50 * params.Shannon
|
||||
defaultGasPrice = 50 * params.Shannon
|
||||
// statuses of candidates
|
||||
statusMasternode = "MASTERNODE"
|
||||
statusSlashed = "SLASHED"
|
||||
statusProposed = "PROPOSED"
|
||||
|
||||
)
|
||||
|
||||
// PublicEthereumAPI provides an API to access Ethereum related information.
|
||||
|
|
@ -494,13 +501,7 @@ func (s *PublicBlockChainAPI) BlockNumber() *big.Int {
|
|||
|
||||
// BlockNumber returns the block number of the chain head.
|
||||
func (s *PublicBlockChainAPI) GetRewardByHash(hash common.Hash) map[string]interface{} {
|
||||
if c, ok := s.b.GetEngine().(*XDPoS.XDPoS); ok {
|
||||
rewards := c.GetRewards(hash)
|
||||
if rewards != nil {
|
||||
return rewards
|
||||
}
|
||||
}
|
||||
return make(map[string]interface{})
|
||||
return s.b.GetRewardByHash(hash)
|
||||
}
|
||||
|
||||
// GetBalance returns the amount of wei for the given address in the state of the
|
||||
|
|
@ -614,6 +615,175 @@ func (s *PublicBlockChainAPI) GetStorageAt(ctx context.Context, address common.A
|
|||
return res[:], state.Error()
|
||||
}
|
||||
|
||||
func (s *PublicBlockChainAPI) GetBlockSignersByHash(ctx context.Context, blockHash common.Hash) ([]common.Address, error) {
|
||||
block, err := s.b.GetBlock(ctx, blockHash)
|
||||
if err != nil || block == nil {
|
||||
return []common.Address{}, err
|
||||
}
|
||||
masternodes, err := s.GetMasternodes(ctx, block)
|
||||
if err != nil || len(masternodes) == 0 {
|
||||
log.Error("Failed to get masternodes", "err", err, "len(masternodes)", len(masternodes))
|
||||
return []common.Address{}, err
|
||||
}
|
||||
return s.rpcOutputBlockSigners(block, ctx, masternodes)
|
||||
}
|
||||
|
||||
func (s *PublicBlockChainAPI) GetBlockSignersByNumber(ctx context.Context, blockNumber rpc.BlockNumber) ([]common.Address, error) {
|
||||
block, err := s.b.BlockByNumber(ctx, blockNumber)
|
||||
if err != nil || block == nil {
|
||||
return []common.Address{}, err
|
||||
}
|
||||
masternodes, err := s.GetMasternodes(ctx, block)
|
||||
if err != nil || len(masternodes) == 0 {
|
||||
log.Error("Failed to get masternodes", "err", err, "len(masternodes)", len(masternodes))
|
||||
return []common.Address{}, err
|
||||
}
|
||||
return s.rpcOutputBlockSigners(block, ctx, masternodes)
|
||||
}
|
||||
|
||||
func (s *PublicBlockChainAPI) GetBlockFinalityByHash(ctx context.Context, blockHash common.Hash) (int32, error) {
|
||||
block, err := s.b.GetBlock(ctx, blockHash)
|
||||
if err != nil || block == nil {
|
||||
return int32(0), err
|
||||
}
|
||||
masternodes, err := s.GetMasternodes(ctx, block)
|
||||
if err != nil || len(masternodes) == 0 {
|
||||
log.Error("Failed to get masternodes", "err", err, "len(masternodes)", len(masternodes))
|
||||
return int32(0), err
|
||||
}
|
||||
blockSigners, err := s.rpcOutputBlockSigners(block, ctx, masternodes)
|
||||
if err != nil {
|
||||
return int32(0), err
|
||||
}
|
||||
return int32(100 * len(blockSigners) / len(masternodes)), err
|
||||
}
|
||||
|
||||
func (s *PublicBlockChainAPI) GetBlockFinalityByNumber(ctx context.Context, blockNumber rpc.BlockNumber) (int32, error) {
|
||||
block, err := s.b.BlockByNumber(ctx, blockNumber)
|
||||
if err != nil || block == nil {
|
||||
return int32(0), err
|
||||
}
|
||||
masternodes, err := s.GetMasternodes(ctx, block)
|
||||
if err != nil || len(masternodes) == 0 {
|
||||
log.Error("Failed to get masternodes", "err", err, "len(masternodes)", len(masternodes))
|
||||
return int32(0), err
|
||||
}
|
||||
blockSigners, err := s.rpcOutputBlockSigners(block, ctx, masternodes)
|
||||
if err != nil {
|
||||
return int32(0), err
|
||||
}
|
||||
return int32(100 * len(blockSigners) / len(masternodes)), err
|
||||
}
|
||||
|
||||
// GetMasternodes returns masternodes set at the starting block of epoch of the given block
|
||||
func (s *PublicBlockChainAPI) GetMasternodes(ctx context.Context, b *types.Block) ([]common.Address, error) {
|
||||
var masternodes []common.Address
|
||||
if b.Number().Int64() >= 0 {
|
||||
curBlockNumber := b.Number().Uint64()
|
||||
prevBlockNumber := curBlockNumber + (common.MergeSignRange - (curBlockNumber % common.MergeSignRange))
|
||||
latestBlockNumber := s.b.CurrentBlock().Number().Uint64()
|
||||
if prevBlockNumber >= latestBlockNumber || !s.b.ChainConfig().IsTIP2019(b.Number()) {
|
||||
prevBlockNumber = curBlockNumber
|
||||
}
|
||||
if engine, ok := s.b.GetEngine().(*XDPoS.XDPoS); ok {
|
||||
// Get block epoc latest.
|
||||
lastCheckpointNumber := prevBlockNumber - (prevBlockNumber % s.b.ChainConfig().XDPoS.Epoch)
|
||||
prevCheckpointBlock, _ := s.b.BlockByNumber(ctx, rpc.BlockNumber(lastCheckpointNumber))
|
||||
if prevCheckpointBlock != nil {
|
||||
masternodes = engine.GetMasternodesFromCheckpointHeader(prevCheckpointBlock.Header(), curBlockNumber, s.b.ChainConfig().XDPoS.Epoch)
|
||||
}
|
||||
} else {
|
||||
log.Error("Undefined XDPoS consensus engine")
|
||||
}
|
||||
}
|
||||
return masternodes, nil
|
||||
}
|
||||
|
||||
|
||||
// GetCandidateStatus returns status of the given candidate at a specified epochNumber
|
||||
func (s *PublicBlockChainAPI) GetCandidateStatus(ctx context.Context, coinbaseAddress common.Address, epochNumber rpc.EpochNumber) (string, error) {
|
||||
var (
|
||||
block *types.Block
|
||||
masternodes, penaltyList, candidates, proposedList []common.Address
|
||||
penalties []byte
|
||||
err error
|
||||
)
|
||||
block = s.b.CurrentBlock()
|
||||
epoch := s.b.ChainConfig().XDPoS.Epoch
|
||||
// TODO: we currently support the latest epoch only
|
||||
//if epochNumber == rpc.LatestEpochNumber {
|
||||
// block = s.b.CurrentBlock()
|
||||
//} else {
|
||||
// checkpointNumber := rpc.BlockNumber((uint64(epochNumber) - 1) * epoch)
|
||||
// if checkpointNumber < 0 {
|
||||
// checkpointNumber = 0
|
||||
// }
|
||||
// block, err = s.b.BlockByNumber(ctx, checkpointNumber)
|
||||
// if err != nil || block == nil {
|
||||
// return "", err
|
||||
// }
|
||||
//}
|
||||
blockNum := block.Number().Uint64()
|
||||
masternodes, err = s.GetMasternodes(ctx, block)
|
||||
if err != nil || len(masternodes) == 0 {
|
||||
log.Error("Failed to get masternodes", "err", err, "len(masternodes)", len(masternodes))
|
||||
return "", err
|
||||
}
|
||||
for _, masternode := range masternodes {
|
||||
if coinbaseAddress == masternode {
|
||||
return statusMasternode, nil
|
||||
}
|
||||
}
|
||||
|
||||
// look up recent checkpoint headers to get penalty list
|
||||
for i := 0; i <= common.LimitPenaltyEpoch; i++ {
|
||||
if blockNum > uint64(i) * epoch {
|
||||
blockCheckpointNumber := rpc.BlockNumber(blockNum - (blockNum % epoch) - (uint64(i) * epoch))
|
||||
blockCheckpoint, err := s.b.BlockByNumber(ctx, blockCheckpointNumber)
|
||||
if err != nil {
|
||||
log.Error("Failed to get block by number", "num", blockCheckpointNumber, "err", err)
|
||||
continue
|
||||
}
|
||||
penalties = append(penalties, blockCheckpoint.Penalties()...)
|
||||
}
|
||||
}
|
||||
if len(penalties) > 0 {
|
||||
penaltyList = common.ExtractAddressFromBytes(penalties)
|
||||
for _, pen := range penaltyList {
|
||||
if coinbaseAddress == pen {
|
||||
return statusSlashed, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// read smart contract to get candidate list
|
||||
client, err := s.b.GetIPCClient()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
addr := common.HexToAddress(common.MasternodeVotingSMC)
|
||||
validator, err := contractValidator.NewXDCValidator(addr, client)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
opts := new(bind.CallOpts)
|
||||
candidates, err = validator.GetCandidates(opts)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
// exclude masternodes
|
||||
proposedList = common.RemoveItemFromArray(candidates, masternodes)
|
||||
// exclude penalties
|
||||
proposedList = common.RemoveItemFromArray(proposedList, penaltyList)
|
||||
|
||||
for _, proposed := range proposedList {
|
||||
if coinbaseAddress == proposed {
|
||||
return statusProposed, nil
|
||||
}
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// CallArgs represents the arguments for a call.
|
||||
type CallArgs struct {
|
||||
From common.Address `json:"from"`
|
||||
|
|
@ -860,28 +1030,46 @@ func (s *PublicBlockChainAPI) rpcOutputBlock(b *types.Block, inclTx bool, fullTx
|
|||
uncleHashes[i] = uncle.Hash()
|
||||
}
|
||||
fields["uncles"] = uncleHashes
|
||||
return fields, nil
|
||||
}
|
||||
|
||||
func (s *PublicBlockChainAPI) rpcOutputBlockSigners(b *types.Block, ctx context.Context, masternodes []common.Address) ([]common.Address, error) {
|
||||
// Get signers for block.
|
||||
client, err := s.b.GetIPCClient()
|
||||
if err != nil {
|
||||
log.Error("Fail to connect IPC client for block status", "error", err)
|
||||
return []common.Address{}, err
|
||||
}
|
||||
|
||||
var signers []common.Address
|
||||
var filterSigners []common.Address
|
||||
finality := int32(0)
|
||||
if b.Number().Int64() > 0 {
|
||||
addrBlockSigner := common.HexToAddress(common.BlockSigners)
|
||||
signers, err = contracts.GetSignersFromContract(addrBlockSigner, client, b.Hash())
|
||||
if err != nil {
|
||||
log.Error("Fail to get signers from block signer SC.", "error", err)
|
||||
blockNumber := b.Number().Uint64()
|
||||
signedBlockNumber := blockNumber + (common.MergeSignRange - (blockNumber % common.MergeSignRange))
|
||||
latestBlockNumber := s.b.CurrentBlock().Number()
|
||||
if signedBlockNumber >= latestBlockNumber.Uint64() || !s.b.ChainConfig().IsTIP2019(b.Number()) {
|
||||
signedBlockNumber = blockNumber
|
||||
}
|
||||
// Get block epoc latest.
|
||||
if s.b.ChainConfig().XDPoS != nil {
|
||||
engine := s.b.GetEngine()
|
||||
lastCheckpointNumber := rpc.BlockNumber(b.Number().Uint64() - (b.Number().Uint64() % s.b.ChainConfig().XDPoS.Epoch))
|
||||
prevCheckpointBlock, _ := s.b.BlockByNumber(ctx, lastCheckpointNumber)
|
||||
if engine, ok := s.b.GetEngine().(*XDPoS.XDPoS); ok {
|
||||
// Get block epoc latest.
|
||||
lastCheckpointNumber := signedBlockNumber - (signedBlockNumber % s.b.ChainConfig().XDPoS.Epoch)
|
||||
prevCheckpointBlock, _ := s.b.BlockByNumber(ctx, rpc.BlockNumber(lastCheckpointNumber))
|
||||
if prevCheckpointBlock != nil {
|
||||
masternodes := engine.(*XDPoS.XDPoS).GetMasternodesFromCheckpointHeader(prevCheckpointBlock.Header(), b.Number().Uint64(), s.b.ChainConfig().XDPoS.Epoch)
|
||||
masternodes := engine.GetMasternodesFromCheckpointHeader(prevCheckpointBlock.Header(), blockNumber, s.b.ChainConfig().XDPoS.Epoch)
|
||||
signedBlock, _ := s.b.BlockByNumber(ctx, rpc.BlockNumber(signedBlockNumber))
|
||||
if s.b.ChainConfig().IsTIPSigning(latestBlockNumber) {
|
||||
signers, err = GetSignersFromBlocks(s.b, signedBlock.NumberU64(), signedBlock.Hash(), masternodes)
|
||||
} else {
|
||||
signers, err = contracts.GetSignersByExecutingEVM(common.HexToAddress(common.BlockSigners), client, signedBlock.Hash())
|
||||
}
|
||||
if err != nil {
|
||||
log.Error("Fail to get signers from block signer SC.", "error", err)
|
||||
return nil, err
|
||||
}
|
||||
validator, _ := engine.RecoverValidator(b.Header())
|
||||
creator, _ := engine.RecoverSigner(b.Header())
|
||||
signers = append(signers, validator)
|
||||
signers = append(signers, creator)
|
||||
countFinality := 0
|
||||
for _, masternode := range masternodes {
|
||||
for _, signer := range signers {
|
||||
|
|
@ -892,14 +1080,12 @@ func (s *PublicBlockChainAPI) rpcOutputBlock(b *types.Block, inclTx bool, fullTx
|
|||
}
|
||||
}
|
||||
}
|
||||
finality = int32(countFinality * 100 / len(masternodes))
|
||||
}
|
||||
} else {
|
||||
log.Error("Undefined XDPoS consensus engine")
|
||||
}
|
||||
}
|
||||
fields["signers"] = filterSigners
|
||||
fields["finality"] = finality
|
||||
|
||||
return fields, nil
|
||||
return filterSigners, nil
|
||||
}
|
||||
|
||||
// RPCTransaction represents a transaction that will serialize to the RPC representation of a transaction
|
||||
|
|
@ -1533,3 +1719,52 @@ func (s *PublicNetAPI) PeerCount() hexutil.Uint {
|
|||
func (s *PublicNetAPI) Version() string {
|
||||
return fmt.Sprintf("%d", s.networkVersion)
|
||||
}
|
||||
|
||||
func GetSignersFromBlocks(b Backend, blockNumber uint64, blockHash common.Hash, masternodes []common.Address) ([]common.Address, error) {
|
||||
var addrs []common.Address
|
||||
mapMN := map[common.Address]bool{}
|
||||
for _, node := range masternodes {
|
||||
mapMN[node] = true
|
||||
}
|
||||
if engine, ok := b.GetEngine().(*XDPoS.XDPoS); ok {
|
||||
limitNumber := blockNumber - blockNumber%b.ChainConfig().XDPoS.Epoch + 2*b.ChainConfig().XDPoS.Epoch - 1
|
||||
currentNumber := b.CurrentBlock().NumberU64()
|
||||
if limitNumber > currentNumber {
|
||||
limitNumber = currentNumber
|
||||
}
|
||||
for i := blockNumber + 1; i <= limitNumber; i++ {
|
||||
header, err := b.HeaderByNumber(nil, rpc.BlockNumber(i))
|
||||
if err != nil {
|
||||
return addrs, err
|
||||
}
|
||||
signData, ok := engine.BlockSigners.Get(header.Hash())
|
||||
var signTxs []*types.Transaction = nil
|
||||
if !ok {
|
||||
blockData, err := b.BlockByNumber(nil, rpc.BlockNumber(i))
|
||||
if err != nil {
|
||||
return addrs, err
|
||||
}
|
||||
signTxs = []*types.Transaction{}
|
||||
for _, tx := range blockData.Transactions() {
|
||||
if tx.IsSigningTransaction() {
|
||||
signTxs = append(signTxs, tx)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
signTxs = signData.([]*types.Transaction)
|
||||
}
|
||||
for _, signtx := range signTxs {
|
||||
blkHash := common.BytesToHash(signtx.Data()[len(signtx.Data())-32:])
|
||||
from := *signtx.From()
|
||||
if blkHash == blockHash && mapMN[from] {
|
||||
addrs = append(addrs, from)
|
||||
delete(mapMN, from)
|
||||
}
|
||||
}
|
||||
if len(mapMN) == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return addrs, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,8 +18,10 @@ package les
|
|||
|
||||
import (
|
||||
"context"
|
||||
"github.com/ethereum/go-ethereum/consensus/XDPoS"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"math/big"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
|
|
@ -202,10 +204,24 @@ func (b *LesApiBackend) GetEngine() consensus.Engine {
|
|||
return b.eth.engine
|
||||
}
|
||||
func (s *LesApiBackend) GetRewardByHash(hash common.Hash) map[string]interface{} {
|
||||
if c, ok := s.eth.Engine().(*XDPoS.XDPoS); ok {
|
||||
rewards := c.GetRewards(hash)
|
||||
if rewards != nil {
|
||||
return rewards
|
||||
header := s.eth.blockchain.GetHeaderByHash(hash)
|
||||
if header != nil {
|
||||
data, err := ioutil.ReadFile(filepath.Join(common.StoreRewardFolder, header.Number.String()+"."+header.Hash().Hex()))
|
||||
if err == nil {
|
||||
rewards := make(map[string]interface{})
|
||||
err = json.Unmarshal(data, &rewards)
|
||||
if err == nil {
|
||||
return rewards
|
||||
}
|
||||
} else {
|
||||
data, err = ioutil.ReadFile(filepath.Join(common.StoreRewardFolder, header.Number.String()+"."+header.HashNoValidator().Hex()))
|
||||
if err == nil {
|
||||
rewards := make(map[string]interface{})
|
||||
err = json.Unmarshal(data, &rewards)
|
||||
if err == nil {
|
||||
return rewards
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return make(map[string]interface{})
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package miner
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"os"
|
||||
|
|
@ -410,8 +411,10 @@ func (self *worker) wait() {
|
|||
}
|
||||
}
|
||||
// Send tx sign to smart contract blockSigners.
|
||||
if err := contracts.CreateTransactionSign(self.config, self.eth.TxPool(), self.eth.AccountManager(), block, self.chainDb); err != nil {
|
||||
log.Error("Fail to create tx sign for signer", "error", "err")
|
||||
if block.NumberU64()%common.MergeSignRange == 0 || !self.config.IsTIP2019(block.Number()) {
|
||||
if err := contracts.CreateTransactionSign(self.config, self.eth.TxPool(), self.eth.AccountManager(), block, self.chainDb); err != nil {
|
||||
log.Error("Fail to create tx sign for signer", "error", "err")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -552,6 +555,7 @@ func (self *worker) commitNewWork() {
|
|||
if atomic.LoadInt32(&self.mining) == 1 {
|
||||
header.Coinbase = self.coinbase
|
||||
}
|
||||
|
||||
if err := self.engine.Prepare(self.chain, header); err != nil {
|
||||
log.Error("Failed to prepare header for new block", "err", err)
|
||||
return
|
||||
|
|
@ -580,12 +584,22 @@ func (self *worker) commitNewWork() {
|
|||
if self.config.DAOForkSupport && self.config.DAOForkBlock != nil && self.config.DAOForkBlock.Cmp(header.Number) == 0 {
|
||||
misc.ApplyDAOHardFork(work.state)
|
||||
}
|
||||
pending, err := self.eth.TxPool().Pending()
|
||||
if err != nil {
|
||||
log.Error("Failed to fetch pending transactions", "err", err)
|
||||
return
|
||||
if common.TIPSigning.Cmp(header.Number) == 0 {
|
||||
work.state.DeleteAddress(common.HexToAddress(common.BlockSigners))
|
||||
}
|
||||
// won't grasp txs at checkpoint
|
||||
var (
|
||||
txs *types.TransactionsByPriceAndNonce
|
||||
specialTxs types.Transactions
|
||||
)
|
||||
if self.config.XDPoS != nil && header.Number.Uint64()%self.config.XDPoS.Epoch != 0 {
|
||||
pending, err := self.eth.TxPool().Pending()
|
||||
if err != nil {
|
||||
log.Error("Failed to fetch pending transactions", "err", err)
|
||||
return
|
||||
}
|
||||
txs, specialTxs = types.NewTransactionsByPriceAndNonce(self.current.signer, pending, signers)
|
||||
}
|
||||
txs, specialTxs := types.NewTransactionsByPriceAndNonce(self.current.signer, pending, signers)
|
||||
work.commitTransactions(self.mux, txs, specialTxs, self.chain, self.coinbase)
|
||||
|
||||
// compute uncles for the new block.
|
||||
|
|
@ -618,7 +632,7 @@ func (self *worker) commitNewWork() {
|
|||
return
|
||||
}
|
||||
if atomic.LoadInt32(&self.mining) == 1 {
|
||||
log.Info("Committing new block", "number", work.Block.Number(), "txs", work.tcount, "special txs", len(specialTxs), "uncles", len(uncles), "elapsed", common.PrettyDuration(time.Since(tstart)))
|
||||
log.Info("Committing new block", "number", work.Block.Number(), "txs", work.tcount, "special-txs", len(specialTxs), "uncles", len(uncles), "elapsed", common.PrettyDuration(time.Since(tstart)))
|
||||
self.unconfirmed.Shift(work.Block.NumberU64() - 1)
|
||||
self.lastParentBlockCommit = parent.Hash().Hex()
|
||||
}
|
||||
|
|
@ -661,6 +675,17 @@ func (env *Work) commitTransactions(mux *event.TypeMux, txs *types.TransactionsB
|
|||
log.Trace("Ignoring reply protected special transaction", "hash", tx.Hash(), "eip155", env.config.EIP155Block)
|
||||
continue
|
||||
}
|
||||
if tx.To().Hex() == common.BlockSigners {
|
||||
if len(tx.Data()) < 68 {
|
||||
log.Trace("Data special transaction invalid length", "hash", tx.Hash(), "data", len(tx.Data()))
|
||||
continue
|
||||
}
|
||||
blkNumber := binary.BigEndian.Uint64(tx.Data()[8:40])
|
||||
if blkNumber >= env.header.Number.Uint64() || blkNumber <= env.header.Number.Uint64()-env.config.XDPoS.Epoch*2 {
|
||||
log.Trace("Data special transaction invalid number", "hash", tx.Hash(), "blkNumber", blkNumber, "miner", env.header.Number)
|
||||
continue
|
||||
}
|
||||
}
|
||||
// Start executing the transaction
|
||||
env.state.Prepare(tx.Hash(), common.Hash{}, env.tcount)
|
||||
nonce := env.state.GetNonce(from)
|
||||
|
|
@ -694,6 +719,10 @@ func (env *Work) commitTransactions(mux *event.TypeMux, txs *types.TransactionsB
|
|||
log.Trace("Not enough gas for further transactions", "gp", gp)
|
||||
break
|
||||
}
|
||||
if txs == nil {
|
||||
log.Info("this block has no transaction")
|
||||
break
|
||||
}
|
||||
// Retrieve the next transaction and abort if all done
|
||||
tx := txs.Peek()
|
||||
if tx == nil {
|
||||
|
|
|
|||
|
|
@ -190,14 +190,14 @@ func (s *Server) serveRequest(codec ServerCodec, singleShot bool, options CodecO
|
|||
if singleShot {
|
||||
if batch {
|
||||
for _, req := range reqs {
|
||||
if req.callb != nil && req.callb.method.Name == "SendTransaction" {
|
||||
if req.callb != nil && req.callb.method.Name == "EnabledRPCSendTransaction" {
|
||||
codec.Write(codec.CreateErrorResponse(&req.id, &invalidRequestError{message: "Only support send transaction with ipc"}))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
s.execBatch(ctx, codec, reqs)
|
||||
} else {
|
||||
if reqs[0].callb != nil && reqs[0].callb.method.Name == "SendTransaction" {
|
||||
if reqs[0].callb != nil && reqs[0].callb.method.Name == "EnabledRPCSendTransaction" {
|
||||
codec.Write(codec.CreateErrorResponse(&reqs[0].id, &invalidRequestError{message: "Only support send transaction with ipc"}))
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue