From 251c9bd89b0938daa0d00808447da1e7d595a77b Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Wed, 6 Jul 2022 11:52:06 +0300 Subject: [PATCH] block: push PrevStateRoot data into stack item, fix #2551 And add compiler/interop support for this. --- pkg/compiler/analysis.go | 3 ++- pkg/core/block/block.go | 9 +++++++-- pkg/interop/native/ledger/block.go | 24 ++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/pkg/compiler/analysis.go b/pkg/compiler/analysis.go index 9e646e638..e0eaee510 100644 --- a/pkg/compiler/analysis.go +++ b/pkg/compiler/analysis.go @@ -371,7 +371,8 @@ func canConvert(s string) bool { s = s[len(interopPrefix):] return s != "/iterator.Iterator" && s != "/storage.Context" && s != "/native/ledger.Block" && s != "/native/ledger.Transaction" && - s != "/native/management.Contract" && s != "/native/neo.AccountState" + s != "/native/management.Contract" && s != "/native/neo.AccountState" && + s != "/native/ledger.BlockSR" } return true } diff --git a/pkg/core/block/block.go b/pkg/core/block/block.go index bdf3e0e57..421b01707 100644 --- a/pkg/core/block/block.go +++ b/pkg/core/block/block.go @@ -216,7 +216,7 @@ func (b *Block) GetExpectedBlockSizeWithoutTransactions(txCount int) int { // ToStackItem converts Block to stackitem.Item. func (b *Block) ToStackItem() stackitem.Item { - return stackitem.NewArray([]stackitem.Item{ + items := []stackitem.Item{ stackitem.NewByteArray(b.Hash().BytesBE()), stackitem.NewBigInteger(big.NewInt(int64(b.Version))), stackitem.NewByteArray(b.PrevHash.BytesBE()), @@ -226,5 +226,10 @@ func (b *Block) ToStackItem() stackitem.Item { stackitem.NewBigInteger(big.NewInt(int64(b.Index))), stackitem.NewByteArray(b.NextConsensus.BytesBE()), stackitem.NewBigInteger(big.NewInt(int64(len(b.Transactions)))), - }) + } + if b.StateRootEnabled { + items = append(items, stackitem.NewByteArray(b.PrevStateRoot.BytesBE())) + } + + return stackitem.NewArray(items) } diff --git a/pkg/interop/native/ledger/block.go b/pkg/interop/native/ledger/block.go index 01fbe1087..84e1a6407 100644 --- a/pkg/interop/native/ledger/block.go +++ b/pkg/interop/native/ledger/block.go @@ -29,3 +29,27 @@ type Block struct { // TransactionsLength represents the length of block's transactions array. TransactionsLength int } + +// BlockSR is a stateroot-enabled Neo block. It's returned from the Ledger contract's +// GetBlock method when StateRootInHeader NeoGo extension is used. Use it only when +// you have it enabled when you need to access PrevStateRoot field, Block is sufficient +// otherwise. To get this data type ToBlockSR method of Block should be used. All of +// the fields are same as in Block except PrevStateRoot. +type BlockSR struct { + Hash interop.Hash256 + Version int + PrevHash interop.Hash256 + MerkleRoot interop.Hash256 + Timestamp int + Nonce int + Index int + NextConsensus interop.Hash160 + TransactionsLength int + // PrevStateRoot is a hash of the previous block's state root. + PrevStateRoot interop.Hash256 +} + +// ToBlockSR converts Block into BlockSR for chains with StateRootInHeader option. +func (b *Block) ToBlockSR() *BlockSR { + return interface{}(b).(*BlockSR) +}