mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-18 02:40:45 +00:00
all: fix missing nil check, close XFN-114 (#1695)
This commit is contained in:
parent
2fd4030cb8
commit
9d85990309
8 changed files with 98 additions and 22 deletions
|
|
@ -189,12 +189,19 @@ func (api *API) GetMasternodesByNumber(number *rpc.BlockNumber) MasternodesStatu
|
||||||
if number == nil || *number == rpc.LatestBlockNumber {
|
if number == nil || *number == rpc.LatestBlockNumber {
|
||||||
header = api.chain.CurrentHeader()
|
header = api.chain.CurrentHeader()
|
||||||
} else if *number == rpc.CommittedBlockNumber {
|
} else if *number == rpc.CommittedBlockNumber {
|
||||||
hash := api.XDPoS.EngineV2.GetLatestCommittedBlockInfo().Hash
|
if info := api.XDPoS.EngineV2.GetLatestCommittedBlockInfo(); info != nil {
|
||||||
header = api.chain.GetHeaderByHash(hash)
|
header = api.chain.GetHeaderByHash(info.Hash)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
header = api.chain.GetHeaderByNumber(uint64(number.Int64()))
|
header = api.chain.GetHeaderByNumber(uint64(number.Int64()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if header == nil {
|
||||||
|
return MasternodesStatus{
|
||||||
|
Error: fmt.Errorf("can not get header by number: %v", number),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
round, err := api.XDPoS.EngineV2.GetRoundNumber(header)
|
round, err := api.XDPoS.EngineV2.GetRoundNumber(header)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return MasternodesStatus{
|
return MasternodesStatus{
|
||||||
|
|
@ -306,14 +313,19 @@ func (api *API) GetV2BlockByHeader(header *types.Header, uncle bool) *V2BlockInf
|
||||||
func (api *API) GetV2BlockByNumber(number *rpc.BlockNumber) *V2BlockInfo {
|
func (api *API) GetV2BlockByNumber(number *rpc.BlockNumber) *V2BlockInfo {
|
||||||
header := api.getHeaderFromApiBlockNum(number)
|
header := api.getHeaderFromApiBlockNum(number)
|
||||||
if header == nil {
|
if header == nil {
|
||||||
return &V2BlockInfo{
|
if number == nil {
|
||||||
Number: big.NewInt(number.Int64()),
|
return &V2BlockInfo{
|
||||||
Error: "can not find block from this number",
|
Error: "can not find block from nil number",
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return &V2BlockInfo{
|
||||||
|
Number: big.NewInt(number.Int64()),
|
||||||
|
Error: "can not find block from this number",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uncle := false
|
return api.GetV2BlockByHeader(header, false)
|
||||||
return api.GetV2BlockByHeader(header, uncle)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Confirm V2 Block Committed Status
|
// Confirm V2 Block Committed Status
|
||||||
|
|
@ -328,11 +340,14 @@ func (api *API) GetV2BlockByHash(blockHash common.Hash) *V2BlockInfo {
|
||||||
|
|
||||||
// confirm this is on the main chain
|
// confirm this is on the main chain
|
||||||
chainHeader := api.chain.GetHeaderByNumber(header.Number.Uint64())
|
chainHeader := api.chain.GetHeaderByNumber(header.Number.Uint64())
|
||||||
uncle := false
|
if chainHeader == nil {
|
||||||
if header.Hash() != chainHeader.Hash() {
|
return &V2BlockInfo{
|
||||||
uncle = true
|
Number: header.Number,
|
||||||
|
Error: "can not find chain header from this number",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uncle := header.Hash() != chainHeader.Hash()
|
||||||
return api.GetV2BlockByHeader(header, uncle)
|
return api.GetV2BlockByHeader(header, uncle)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -361,8 +376,9 @@ func (api *API) getHeaderFromApiBlockNum(number *rpc.BlockNumber) *types.Header
|
||||||
if number == nil || *number == rpc.LatestBlockNumber {
|
if number == nil || *number == rpc.LatestBlockNumber {
|
||||||
header = api.chain.CurrentHeader()
|
header = api.chain.CurrentHeader()
|
||||||
} else if *number == rpc.CommittedBlockNumber {
|
} else if *number == rpc.CommittedBlockNumber {
|
||||||
hash := api.XDPoS.EngineV2.GetLatestCommittedBlockInfo().Hash
|
if info := api.XDPoS.EngineV2.GetLatestCommittedBlockInfo(); info != nil {
|
||||||
header = api.chain.GetHeaderByHash(hash)
|
header = api.chain.GetHeaderByHash(info.Hash)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
header = api.chain.GetHeaderByNumber(uint64(number.Int64()))
|
header = api.chain.GetHeaderByNumber(uint64(number.Int64()))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -877,6 +877,10 @@ func (x *XDPoS_v2) commitBlocks(blockChainReader consensus.ChainReader, proposed
|
||||||
}
|
}
|
||||||
// Find the last two parent block and check their rounds are the continuous
|
// Find the last two parent block and check their rounds are the continuous
|
||||||
parentBlock := blockChainReader.GetHeaderByHash(proposedBlockHeader.ParentHash)
|
parentBlock := blockChainReader.GetHeaderByHash(proposedBlockHeader.ParentHash)
|
||||||
|
if parentBlock == nil {
|
||||||
|
log.Error("[commitBlocks] Fail to get header by parent hash", "hash", proposedBlockHeader.ParentHash)
|
||||||
|
return false, fmt.Errorf("commitBlocks fail to get header by parent hash: %v", proposedBlockHeader.ParentHash)
|
||||||
|
}
|
||||||
|
|
||||||
_, round, _, err := x.getExtraFields(parentBlock)
|
_, round, _, err := x.getExtraFields(parentBlock)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -890,6 +894,10 @@ func (x *XDPoS_v2) commitBlocks(blockChainReader consensus.ChainReader, proposed
|
||||||
|
|
||||||
// If parent round is continuous, we check grandparent
|
// If parent round is continuous, we check grandparent
|
||||||
grandParentBlock := blockChainReader.GetHeaderByHash(parentBlock.ParentHash)
|
grandParentBlock := blockChainReader.GetHeaderByHash(parentBlock.ParentHash)
|
||||||
|
if grandParentBlock == nil {
|
||||||
|
log.Error("[commitBlocks] Fail to get header by grandparent hash", "hash", parentBlock.ParentHash)
|
||||||
|
return false, fmt.Errorf("commitBlocks fail to get header by grandparent hash: %v", parentBlock.ParentHash)
|
||||||
|
}
|
||||||
_, round, _, err = x.getExtraFields(grandParentBlock)
|
_, round, _, err = x.getExtraFields(grandParentBlock)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Fail to execute second DecodeBytesExtraFields for committing block", "parentBlockHash", parentBlock.Hash())
|
log.Error("Fail to execute second DecodeBytesExtraFields for committing block", "parentBlockHash", parentBlock.Hash())
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package engine_v2
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/common"
|
"github.com/XinFinOrg/XDPoSChain/common"
|
||||||
"github.com/XinFinOrg/XDPoSChain/consensus"
|
"github.com/XinFinOrg/XDPoSChain/consensus"
|
||||||
|
|
@ -84,7 +85,12 @@ func (x *XDPoS_v2) getSnapshot(chain consensus.ChainReader, number uint64, isGap
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gapBlockHash := chain.GetHeaderByNumber(gapBlockNum).Hash()
|
gapHeader := chain.GetHeaderByNumber(gapBlockNum)
|
||||||
|
if gapHeader == nil {
|
||||||
|
log.Error("[getSnapshot] Fail to get header", "number", gapBlockNum)
|
||||||
|
return nil, fmt.Errorf("getSnapshot fail to get header by number: %v", gapBlockNum)
|
||||||
|
}
|
||||||
|
gapBlockHash := gapHeader.Hash()
|
||||||
log.Debug("get snapshot from gap block", "number", gapBlockNum, "hash", gapBlockHash.Hex())
|
log.Debug("get snapshot from gap block", "number", gapBlockNum, "hash", gapBlockHash.Hex())
|
||||||
|
|
||||||
// If an in-memory SnapshotV2 was found, use that
|
// If an in-memory SnapshotV2 was found, use that
|
||||||
|
|
|
||||||
|
|
@ -96,6 +96,9 @@ func (x *XDPoS_v2) signSignature(signingHash common.Hash) (types.Signature, erro
|
||||||
signer, signFn := x.signer, x.signFn
|
signer, signFn := x.signer, x.signFn
|
||||||
x.signLock.RUnlock()
|
x.signLock.RUnlock()
|
||||||
|
|
||||||
|
if signFn == nil {
|
||||||
|
return nil, errors.New("signFn is nil")
|
||||||
|
}
|
||||||
signedHash, err := signFn(accounts.Account{Address: signer}, signingHash.Bytes())
|
signedHash, err := signFn(accounts.Account{Address: signer}, signingHash.Bytes())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error %v while signing hash", err)
|
return nil, fmt.Errorf("error %v while signing hash", err)
|
||||||
|
|
@ -182,6 +185,9 @@ func (x *XDPoS_v2) CalculateMissingRounds(chain consensus.ChainReader, header *t
|
||||||
nextHeader := header
|
nextHeader := header
|
||||||
for nextHeader.Number.Cmp(switchInfo.EpochSwitchBlockInfo.Number) > 0 {
|
for nextHeader.Number.Cmp(switchInfo.EpochSwitchBlockInfo.Number) > 0 {
|
||||||
parentHeader := chain.GetHeaderByHash(nextHeader.ParentHash)
|
parentHeader := chain.GetHeaderByHash(nextHeader.ParentHash)
|
||||||
|
if parentHeader == nil {
|
||||||
|
return nil, fmt.Errorf("fail to get header by hash %v: ", nextHeader.ParentHash)
|
||||||
|
}
|
||||||
parentRound, err := x.GetRoundNumber(parentHeader)
|
parentRound, err := x.GetRoundNumber(parentHeader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -299,6 +305,9 @@ func (x *XDPoS_v2) binarySearchBlockByEpochNumber(chain consensus.ChainReader, t
|
||||||
|
|
||||||
func (x *XDPoS_v2) GetBlockByEpochNumber(chain consensus.ChainReader, targetEpochNum uint64) (*types.BlockInfo, error) {
|
func (x *XDPoS_v2) GetBlockByEpochNumber(chain consensus.ChainReader, targetEpochNum uint64) (*types.BlockInfo, error) {
|
||||||
currentHeader := chain.CurrentHeader()
|
currentHeader := chain.CurrentHeader()
|
||||||
|
if currentHeader == nil {
|
||||||
|
return nil, errors.New("current header is nil")
|
||||||
|
}
|
||||||
epochSwitchInfo, err := x.getEpochSwitchInfo(chain, currentHeader, currentHeader.Hash())
|
epochSwitchInfo, err := x.getEpochSwitchInfo(chain, currentHeader, currentHeader.Hash())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -332,6 +341,9 @@ func (x *XDPoS_v2) GetBlockByEpochNumber(chain consensus.ChainReader, targetEpoc
|
||||||
closeEpochNum := uint64(2)
|
closeEpochNum := uint64(2)
|
||||||
if closeEpochNum >= epochNum-targetEpochNum {
|
if closeEpochNum >= epochNum-targetEpochNum {
|
||||||
estBlockHeader := chain.GetHeaderByNumber(estBlockNum.Uint64())
|
estBlockHeader := chain.GetHeaderByNumber(estBlockNum.Uint64())
|
||||||
|
if estBlockHeader == nil {
|
||||||
|
return nil, fmt.Errorf("fail to get est block header by number: %v", estBlockNum)
|
||||||
|
}
|
||||||
epochSwitchInfos, err := x.GetEpochSwitchInfoBetween(chain, estBlockHeader, currentHeader)
|
epochSwitchInfos, err := x.GetEpochSwitchInfoBetween(chain, estBlockHeader, currentHeader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,10 @@ func (x *XDPoS_v2) verifyHeader(chain consensus.ChainReader, header *types.Heade
|
||||||
log.Warn("[verifyHeader] decode extra field error", "err", err)
|
log.Warn("[verifyHeader] decode extra field error", "err", err)
|
||||||
return utils.ErrInvalidV2Extra
|
return utils.ErrInvalidV2Extra
|
||||||
}
|
}
|
||||||
|
if quorumCert == nil {
|
||||||
|
log.Warn("[verifyHeader] quorumCert is nil")
|
||||||
|
return utils.ErrInvalidQuorumCert
|
||||||
|
}
|
||||||
|
|
||||||
minePeriod := uint64(x.config.V2.Config(uint64(round)).MinePeriod)
|
minePeriod := uint64(x.config.V2.Config(uint64(round)).MinePeriod)
|
||||||
if parent.Number.Uint64() >= x.config.V2.SwitchBlock.Uint64() && parent.Time+minePeriod > header.Time {
|
if parent.Number.Uint64() >= x.config.V2.SwitchBlock.Uint64() && parent.Time+minePeriod > header.Time {
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,7 @@ var (
|
||||||
ErrEmptyEpochSwitchValidators = errors.New("empty validators list on epoch switch block")
|
ErrEmptyEpochSwitchValidators = errors.New("empty validators list on epoch switch block")
|
||||||
|
|
||||||
ErrInvalidV2Extra = errors.New("invalid v2 extra in the block")
|
ErrInvalidV2Extra = errors.New("invalid v2 extra in the block")
|
||||||
|
ErrInvalidQuorumCert = errors.New("invalid quorum cert")
|
||||||
ErrInvalidQC = errors.New("invalid QC content")
|
ErrInvalidQC = errors.New("invalid QC content")
|
||||||
ErrInvalidQCSignatures = errors.New("invalid QC Signatures")
|
ErrInvalidQCSignatures = errors.New("invalid QC Signatures")
|
||||||
ErrInvalidTC = errors.New("invalid TC content")
|
ErrInvalidTC = errors.New("invalid TC content")
|
||||||
|
|
|
||||||
|
|
@ -743,7 +743,11 @@ func (bc *BlockChain) repair(head **types.Block) error {
|
||||||
log.Info("Rewound blockchain to past state", "number", (*head).Number(), "hash", (*head).Hash())
|
log.Info("Rewound blockchain to past state", "number", (*head).Number(), "hash", (*head).Hash())
|
||||||
}
|
}
|
||||||
// Otherwise rewind one block and recheck state availability there
|
// Otherwise rewind one block and recheck state availability there
|
||||||
(*head) = bc.GetBlock((*head).ParentHash(), (*head).NumberU64()-1)
|
block := bc.GetBlock((*head).ParentHash(), (*head).NumberU64()-1)
|
||||||
|
if block == nil {
|
||||||
|
panic(fmt.Sprintf("repair fail to get block at number: %v, hash: %v", (*head).NumberU64()-1, (*head).ParentHash()))
|
||||||
|
}
|
||||||
|
(*head) = block
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1018,10 +1022,16 @@ func (bc *BlockChain) GetBlocksHashCache(number uint64) []common.Hash {
|
||||||
func (bc *BlockChain) AreTwoBlockSamePath(bh1 common.Hash, bh2 common.Hash) bool {
|
func (bc *BlockChain) AreTwoBlockSamePath(bh1 common.Hash, bh2 common.Hash) bool {
|
||||||
bl1 := bc.GetBlockByHash(bh1)
|
bl1 := bc.GetBlockByHash(bh1)
|
||||||
bl2 := bc.GetBlockByHash(bh2)
|
bl2 := bc.GetBlockByHash(bh2)
|
||||||
toBlockLevel := bl2.Number().Uint64()
|
if bl1 == nil || bl2 == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
toBlockLevel := bl2.Number().Uint64()
|
||||||
for bl1.Number().Uint64() > toBlockLevel {
|
for bl1.Number().Uint64() > toBlockLevel {
|
||||||
bl1 = bc.GetBlockByHash(bl1.ParentHash())
|
bl1 = bc.GetBlockByHash(bl1.ParentHash())
|
||||||
|
if bl1 == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (bl1.Hash() == bl2.Hash())
|
return (bl1.Hash() == bl2.Hash())
|
||||||
|
|
@ -2141,6 +2151,9 @@ func (bc *BlockChain) getResultBlock(block *types.Block, verifiedM2 bool) (*Resu
|
||||||
var winner []*types.Block
|
var winner []*types.Block
|
||||||
|
|
||||||
parent := bc.GetBlock(block.ParentHash(), block.NumberU64()-1)
|
parent := bc.GetBlock(block.ParentHash(), block.NumberU64()-1)
|
||||||
|
if parent == nil {
|
||||||
|
return nil, fmt.Errorf("fail to get parent block at number: %v, hash: %v", block.NumberU64()-1, block.ParentHash())
|
||||||
|
}
|
||||||
for !bc.HasFullState(parent) {
|
for !bc.HasFullState(parent) {
|
||||||
winner = append(winner, parent)
|
winner = append(winner, parent)
|
||||||
parent = bc.GetBlock(parent.ParentHash(), parent.NumberU64()-1)
|
parent = bc.GetBlock(parent.ParentHash(), parent.NumberU64()-1)
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package hooks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"slices"
|
"slices"
|
||||||
"time"
|
"time"
|
||||||
|
|
@ -72,6 +73,10 @@ func AttachConsensusV2Hooks(adaptor *XDPoS.XDPoS, bc *core.BlockChain, chainConf
|
||||||
|
|
||||||
for i := uint64(1); ; i++ {
|
for i := uint64(1); ; i++ {
|
||||||
parentHeader := chain.GetHeader(parentHash, parentNumber)
|
parentHeader := chain.GetHeader(parentHash, parentNumber)
|
||||||
|
if parentHeader == nil {
|
||||||
|
log.Error("[HookPenalty] fail to get parent header")
|
||||||
|
return []common.Address{}, fmt.Errorf("hook penalty fail to get parent header at number: %v, hash: %v", parentNumber, parentHash)
|
||||||
|
}
|
||||||
isEpochSwitch, _, err := adaptor.EngineV2.IsEpochSwitch(parentHeader)
|
isEpochSwitch, _, err := adaptor.EngineV2.IsEpochSwitch(parentHeader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("[HookPenalty] isEpochSwitch", "err", err)
|
log.Error("[HookPenalty] isEpochSwitch", "err", err)
|
||||||
|
|
@ -149,8 +154,10 @@ func AttachConsensusV2Hooks(adaptor *XDPoS.XDPoS, bc *core.BlockChain, chainConf
|
||||||
signingTxs, ok := adaptor.GetCachedSigningTxs(bhash)
|
signingTxs, ok := adaptor.GetCachedSigningTxs(bhash)
|
||||||
if !ok {
|
if !ok {
|
||||||
block := chain.GetBlock(bhash, blockNumber)
|
block := chain.GetBlock(bhash, blockNumber)
|
||||||
txs := block.Transactions()
|
if block != nil {
|
||||||
signingTxs = adaptor.CacheSigningTxs(bhash, txs)
|
txs := block.Transactions()
|
||||||
|
signingTxs = adaptor.CacheSigningTxs(bhash, txs)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Check signer signed?
|
// Check signer signed?
|
||||||
for _, tx := range signingTxs {
|
for _, tx := range signingTxs {
|
||||||
|
|
@ -221,8 +228,10 @@ func AttachConsensusV2Hooks(adaptor *XDPoS.XDPoS, bc *core.BlockChain, chainConf
|
||||||
signingTxs, ok := adaptor.GetCachedSigningTxs(bhash)
|
signingTxs, ok := adaptor.GetCachedSigningTxs(bhash)
|
||||||
if !ok {
|
if !ok {
|
||||||
block := chain.GetBlock(bhash, blockNumber)
|
block := chain.GetBlock(bhash, blockNumber)
|
||||||
txs := block.Transactions()
|
if block != nil {
|
||||||
signingTxs = adaptor.CacheSigningTxs(bhash, txs)
|
txs := block.Transactions()
|
||||||
|
signingTxs = adaptor.CacheSigningTxs(bhash, txs)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Check signer signed?
|
// Check signer signed?
|
||||||
for _, tx := range signingTxs {
|
for _, tx := range signingTxs {
|
||||||
|
|
@ -404,7 +413,12 @@ func GetSigningTxCount(c *XDPoS.XDPoS, chain consensus.ChainReader, header *type
|
||||||
|
|
||||||
h := header
|
h := header
|
||||||
for i := number - 1; ; i-- {
|
for i := number - 1; ; i-- {
|
||||||
h = chain.GetHeader(h.ParentHash, i)
|
parentHash := h.ParentHash
|
||||||
|
h = chain.GetHeader(parentHash, i)
|
||||||
|
if h == nil {
|
||||||
|
log.Error("[GetSigningTxCount] fail to get header", "number", i, "hash", parentHash)
|
||||||
|
return nil, fmt.Errorf("fail to get header in GetSigningTxCount at number: %v, hash: %v", i, parentHash)
|
||||||
|
}
|
||||||
isEpochSwitch, _, err := c.IsEpochSwitch(h)
|
isEpochSwitch, _, err := c.IsEpochSwitch(h)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -464,8 +478,10 @@ func GetSigningTxCount(c *XDPoS.XDPoS, chain consensus.ChainReader, header *type
|
||||||
if !ok {
|
if !ok {
|
||||||
log.Debug("Failed get from cached", "hash", h.Hash().String(), "number", i)
|
log.Debug("Failed get from cached", "hash", h.Hash().String(), "number", i)
|
||||||
block := chain.GetBlock(h.Hash(), i)
|
block := chain.GetBlock(h.Hash(), i)
|
||||||
txs := block.Transactions()
|
if block != nil {
|
||||||
signingTxs = c.CacheSigningTxs(h.Hash(), txs)
|
txs := block.Transactions()
|
||||||
|
signingTxs = c.CacheSigningTxs(h.Hash(), txs)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for _, tx := range signingTxs {
|
for _, tx := range signingTxs {
|
||||||
blkHash := common.BytesToHash(tx.Data()[len(tx.Data())-32:])
|
blkHash := common.BytesToHash(tx.Data()[len(tx.Data())-32:])
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue