Merge pull request #1792 from nspcc-dev/fix/consensusdata
Remove `ConsensusData` from `Block`
This commit is contained in:
commit
9b0d4e0968
40 changed files with 384 additions and 542 deletions
BIN
cli/testdata/chain50x2.acc
vendored
BIN
cli/testdata/chain50x2.acc
vendored
Binary file not shown.
|
@ -236,7 +236,7 @@ func (chain *FakeChain) GetHeader(hash util.Uint256) (*block.Header, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b.Header(), nil
|
||||
return &b.Header, nil
|
||||
}
|
||||
|
||||
// GetNextBlockValidators implements Blockchainer interface.
|
||||
|
|
|
@ -163,18 +163,15 @@ func NewBlock(t *testing.T, bc blockchainer.Blockchainer, offset uint32, primary
|
|||
hdr, err := bc.GetHeader(h)
|
||||
require.NoError(t, err)
|
||||
b := &block.Block{
|
||||
Base: block.Base{
|
||||
Header: block.Header{
|
||||
PrevHash: hdr.Hash(),
|
||||
Timestamp: (uint64(time.Now().UTC().Unix()) + uint64(hdr.Index)) * 1000,
|
||||
Index: hdr.Index + offset,
|
||||
PrimaryIndex: byte(primary),
|
||||
NextConsensus: witness.ScriptHash(),
|
||||
Script: witness,
|
||||
Network: bc.GetConfig().Magic,
|
||||
},
|
||||
ConsensusData: block.ConsensusData{
|
||||
PrimaryIndex: primary,
|
||||
Nonce: 1111,
|
||||
},
|
||||
Transactions: txs,
|
||||
}
|
||||
b.RebuildMerkleRoot()
|
||||
|
|
|
@ -18,7 +18,7 @@ var (
|
|||
// Custom builtin utility functions.
|
||||
customBuiltins = []string{
|
||||
"FromAddress", "Equals", "Remove",
|
||||
"ToBool", "ToByteArray", "ToInteger",
|
||||
"ToBool", "ToBytes", "ToString", "ToInteger",
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ func getFunctionName(typ string) string {
|
|||
case "bool":
|
||||
return "Bool"
|
||||
case "[]byte":
|
||||
return "ByteArray"
|
||||
return "Bytes"
|
||||
case "int":
|
||||
return "Integer"
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ var _ block.Block = (*neoBlock)(nil)
|
|||
|
||||
// Sign implements block.Block interface.
|
||||
func (n *neoBlock) Sign(key crypto.PrivateKey) error {
|
||||
data := n.Base.GetSignedPart()
|
||||
data := n.Header.GetSignedPart()
|
||||
sig, err := key.Sign(data[:])
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -33,7 +33,7 @@ func (n *neoBlock) Sign(key crypto.PrivateKey) error {
|
|||
|
||||
// Verify implements block.Block interface.
|
||||
func (n *neoBlock) Verify(key crypto.PublicKey, sign []byte) error {
|
||||
data := n.Base.GetSignedPart()
|
||||
data := n.Header.GetSignedPart()
|
||||
return key.Verify(data, sign)
|
||||
}
|
||||
|
||||
|
@ -71,7 +71,7 @@ func (n *neoBlock) Timestamp() uint64 { return n.Block.Timestamp * nsInMs }
|
|||
func (n *neoBlock) Index() uint32 { return n.Block.Index }
|
||||
|
||||
// ConsensusData implements block.Block interface.
|
||||
func (n *neoBlock) ConsensusData() uint64 { return n.Block.ConsensusData.Nonce }
|
||||
func (n *neoBlock) ConsensusData() uint64 { return 0 }
|
||||
|
||||
// NextConsensus implements block.Block interface.
|
||||
func (n *neoBlock) NextConsensus() util.Uint160 { return n.Block.NextConsensus }
|
||||
|
|
|
@ -34,9 +34,6 @@ func TestNeoBlock_Setters(t *testing.T) {
|
|||
// 777ms -> 777000000ns
|
||||
require.EqualValues(t, 777000000, b.Timestamp())
|
||||
|
||||
b.Block.ConsensusData.Nonce = 456
|
||||
require.EqualValues(t, 456, b.ConsensusData())
|
||||
|
||||
b.Block.MerkleRoot = util.Uint256{1, 2, 3, 4}
|
||||
require.Equal(t, util.Uint256{1, 2, 3, 4}, b.MerkleRoot())
|
||||
|
||||
|
|
|
@ -662,14 +662,12 @@ func (s *service) newBlockFromContext(ctx *dbft.Context) block.Block {
|
|||
block.Block.NextConsensus = crypto.Hash160(script)
|
||||
block.Block.PrevHash = ctx.PrevHash
|
||||
block.Block.Version = ctx.Version
|
||||
block.Block.ConsensusData.Nonce = ctx.Nonce
|
||||
|
||||
primaryIndex := uint32(ctx.PrimaryIndex)
|
||||
block.Block.ConsensusData.PrimaryIndex = primaryIndex
|
||||
primaryIndex := byte(ctx.PrimaryIndex)
|
||||
block.Block.PrimaryIndex = primaryIndex
|
||||
|
||||
hashes := make([]util.Uint256, len(ctx.TransactionHashes)+1)
|
||||
hashes[0] = block.Block.ConsensusData.Hash()
|
||||
copy(hashes[1:], ctx.TransactionHashes)
|
||||
hashes := make([]util.Uint256, len(ctx.TransactionHashes))
|
||||
copy(hashes, ctx.TransactionHashes)
|
||||
block.Block.MerkleRoot = hash.CalcMerkleRoot(hashes)
|
||||
|
||||
return block
|
||||
|
|
|
@ -14,10 +14,8 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
// MaxContentsPerBlock is the maximum number of contents (transactions + consensus data) per block.
|
||||
MaxContentsPerBlock = math.MaxUint16
|
||||
// MaxTransactionsPerBlock is the maximum number of transactions per block.
|
||||
MaxTransactionsPerBlock = MaxContentsPerBlock - 1
|
||||
MaxTransactionsPerBlock = math.MaxUint16
|
||||
)
|
||||
|
||||
// ErrMaxContentsPerBlock is returned when the maximum number of contents per block is reached.
|
||||
|
@ -26,10 +24,7 @@ var ErrMaxContentsPerBlock = errors.New("the number of contents exceeds the maxi
|
|||
// Block represents one block in the chain.
|
||||
type Block struct {
|
||||
// The base of the block.
|
||||
Base
|
||||
|
||||
// Primary index and nonce
|
||||
ConsensusData ConsensusData `json:"consensusdata"`
|
||||
Header
|
||||
|
||||
// Transaction list.
|
||||
Transactions []*transaction.Transaction
|
||||
|
@ -40,29 +35,19 @@ type Block struct {
|
|||
|
||||
// auxBlockOut is used for JSON i/o.
|
||||
type auxBlockOut struct {
|
||||
ConsensusData ConsensusData `json:"consensusdata"`
|
||||
Transactions []*transaction.Transaction `json:"tx"`
|
||||
}
|
||||
|
||||
// auxBlockIn is used for JSON i/o.
|
||||
type auxBlockIn struct {
|
||||
ConsensusData ConsensusData `json:"consensusdata"`
|
||||
Transactions []json.RawMessage `json:"tx"`
|
||||
}
|
||||
|
||||
// Header returns the Header of the Block.
|
||||
func (b *Block) Header() *Header {
|
||||
return &Header{
|
||||
Base: b.Base,
|
||||
}
|
||||
}
|
||||
|
||||
// ComputeMerkleRoot computes Merkle tree root hash based on actual block's data.
|
||||
func (b *Block) ComputeMerkleRoot() util.Uint256 {
|
||||
hashes := make([]util.Uint256, len(b.Transactions)+1)
|
||||
hashes[0] = b.ConsensusData.Hash()
|
||||
hashes := make([]util.Uint256, len(b.Transactions))
|
||||
for i, tx := range b.Transactions {
|
||||
hashes[i+1] = tx.Hash()
|
||||
hashes[i] = tx.Hash()
|
||||
}
|
||||
|
||||
return hash.CalcMerkleRoot(hashes)
|
||||
|
@ -79,7 +64,7 @@ func (b *Block) RebuildMerkleRoot() {
|
|||
// set to true.
|
||||
func NewBlockFromTrimmedBytes(network netmode.Magic, stateRootEnabled bool, b []byte) (*Block, error) {
|
||||
block := &Block{
|
||||
Base: Base{
|
||||
Header: Header{
|
||||
Network: network,
|
||||
StateRootEnabled: stateRootEnabled,
|
||||
},
|
||||
|
@ -87,27 +72,18 @@ func NewBlockFromTrimmedBytes(network netmode.Magic, stateRootEnabled bool, b []
|
|||
}
|
||||
|
||||
br := io.NewBinReaderFromBuf(b)
|
||||
block.decodeHashableFields(br)
|
||||
|
||||
_ = br.ReadB()
|
||||
|
||||
block.Script.DecodeBinary(br)
|
||||
|
||||
block.Header.DecodeBinary(br)
|
||||
lenHashes := br.ReadVarUint()
|
||||
if lenHashes > MaxContentsPerBlock {
|
||||
if lenHashes > MaxTransactionsPerBlock {
|
||||
return nil, ErrMaxContentsPerBlock
|
||||
}
|
||||
if lenHashes > 0 {
|
||||
var consensusDataHash util.Uint256
|
||||
consensusDataHash.DecodeBinary(br)
|
||||
lenTX := lenHashes - 1
|
||||
block.Transactions = make([]*transaction.Transaction, lenTX)
|
||||
for i := 0; i < int(lenTX); i++ {
|
||||
block.Transactions = make([]*transaction.Transaction, lenHashes)
|
||||
for i := 0; i < int(lenHashes); i++ {
|
||||
var hash util.Uint256
|
||||
hash.DecodeBinary(br)
|
||||
block.Transactions[i] = transaction.NewTrimmedTX(hash)
|
||||
}
|
||||
block.ConsensusData.DecodeBinary(br)
|
||||
}
|
||||
|
||||
return block, br.Err
|
||||
|
@ -116,7 +92,7 @@ func NewBlockFromTrimmedBytes(network netmode.Magic, stateRootEnabled bool, b []
|
|||
// New creates a new blank block tied to the specific network.
|
||||
func New(network netmode.Magic, stateRootEnabled bool) *Block {
|
||||
return &Block{
|
||||
Base: Base{
|
||||
Header: Header{
|
||||
Network: network,
|
||||
StateRootEnabled: stateRootEnabled,
|
||||
},
|
||||
|
@ -128,20 +104,14 @@ func New(network netmode.Magic, stateRootEnabled bool) *Block {
|
|||
// Notice that only the hashes of the transactions are stored.
|
||||
func (b *Block) Trim() ([]byte, error) {
|
||||
buf := io.NewBufBinWriter()
|
||||
b.encodeHashableFields(buf.BinWriter)
|
||||
buf.WriteB(1)
|
||||
b.Script.EncodeBinary(buf.BinWriter)
|
||||
|
||||
buf.WriteVarUint(uint64(len(b.Transactions)) + 1)
|
||||
hash := b.ConsensusData.Hash()
|
||||
hash.EncodeBinary(buf.BinWriter)
|
||||
b.Header.EncodeBinary(buf.BinWriter)
|
||||
|
||||
buf.WriteVarUint(uint64(len(b.Transactions)))
|
||||
for _, tx := range b.Transactions {
|
||||
h := tx.Hash()
|
||||
h.EncodeBinary(buf.BinWriter)
|
||||
}
|
||||
|
||||
b.ConsensusData.EncodeBinary(buf.BinWriter)
|
||||
if buf.Err != nil {
|
||||
return nil, buf.Err
|
||||
}
|
||||
|
@ -152,19 +122,14 @@ func (b *Block) Trim() ([]byte, error) {
|
|||
// DecodeBinary decodes the block from the given BinReader, implementing
|
||||
// Serializable interface.
|
||||
func (b *Block) DecodeBinary(br *io.BinReader) {
|
||||
b.Base.DecodeBinary(br)
|
||||
b.Header.DecodeBinary(br)
|
||||
contentsCount := br.ReadVarUint()
|
||||
if contentsCount == 0 {
|
||||
br.Err = errors.New("invalid block format")
|
||||
return
|
||||
}
|
||||
if contentsCount > MaxContentsPerBlock {
|
||||
if contentsCount > MaxTransactionsPerBlock {
|
||||
br.Err = ErrMaxContentsPerBlock
|
||||
return
|
||||
}
|
||||
b.ConsensusData.DecodeBinary(br)
|
||||
txes := make([]*transaction.Transaction, contentsCount-1)
|
||||
for i := 0; i < int(contentsCount)-1; i++ {
|
||||
txes := make([]*transaction.Transaction, contentsCount)
|
||||
for i := 0; i < int(contentsCount); i++ {
|
||||
tx := &transaction.Transaction{Network: b.Network}
|
||||
tx.DecodeBinary(br)
|
||||
txes[i] = tx
|
||||
|
@ -178,9 +143,8 @@ func (b *Block) DecodeBinary(br *io.BinReader) {
|
|||
// EncodeBinary encodes the block to the given BinWriter, implementing
|
||||
// Serializable interface.
|
||||
func (b *Block) EncodeBinary(bw *io.BinWriter) {
|
||||
b.Base.EncodeBinary(bw)
|
||||
bw.WriteVarUint(uint64(len(b.Transactions) + 1))
|
||||
b.ConsensusData.EncodeBinary(bw)
|
||||
b.Header.EncodeBinary(bw)
|
||||
bw.WriteVarUint(uint64(len(b.Transactions)))
|
||||
for i := 0; i < len(b.Transactions); i++ {
|
||||
b.Transactions[i].EncodeBinary(bw)
|
||||
}
|
||||
|
@ -202,13 +166,12 @@ func (b *Block) Compare(item queue.Item) int {
|
|||
// MarshalJSON implements json.Marshaler interface.
|
||||
func (b Block) MarshalJSON() ([]byte, error) {
|
||||
auxb, err := json.Marshal(auxBlockOut{
|
||||
ConsensusData: b.ConsensusData,
|
||||
Transactions: b.Transactions,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
baseBytes, err := json.Marshal(b.Base)
|
||||
baseBytes, err := json.Marshal(b.Header)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -231,7 +194,7 @@ func (b *Block) UnmarshalJSON(data []byte) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = json.Unmarshal(data, &b.Base)
|
||||
err = json.Unmarshal(data, &b.Header)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -246,9 +209,5 @@ func (b *Block) UnmarshalJSON(data []byte) error {
|
|||
b.Transactions = append(b.Transactions, tx)
|
||||
}
|
||||
}
|
||||
b.ConsensusData = auxb.ConsensusData
|
||||
// Some tests rely on hash presence and we're usually precomputing
|
||||
// other hashes upon deserialization.
|
||||
_ = b.ConsensusData.Hash()
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -1,216 +0,0 @@
|
|||
package block
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
)
|
||||
|
||||
// Base holds the base info of a block
|
||||
type Base struct {
|
||||
// Version of the block.
|
||||
Version uint32
|
||||
|
||||
// hash of the previous block.
|
||||
PrevHash util.Uint256
|
||||
|
||||
// Root hash of a transaction list.
|
||||
MerkleRoot util.Uint256
|
||||
|
||||
// Timestamp is a millisecond-precision timestamp.
|
||||
// The time stamp of each block must be later than previous block's time stamp.
|
||||
// Generally the difference of two block's time stamp is about 15 seconds and imprecision is allowed.
|
||||
// The height of the block must be exactly equal to the height of the previous block plus 1.
|
||||
Timestamp uint64
|
||||
|
||||
// index/height of the block
|
||||
Index uint32
|
||||
|
||||
// Contract address of the next miner
|
||||
NextConsensus util.Uint160
|
||||
|
||||
// Script used to validate the block
|
||||
Script transaction.Witness
|
||||
|
||||
// Network magic number this block belongs to. This one actually is not
|
||||
// a part of the wire-representation of Block, but it's absolutely
|
||||
// necessary for correct signing/verification.
|
||||
Network netmode.Magic
|
||||
|
||||
// StateRootEnabled specifies if header contains state root.
|
||||
StateRootEnabled bool
|
||||
// PrevStateRoot is state root of the previous block.
|
||||
PrevStateRoot util.Uint256
|
||||
|
||||
// Hash of this block, created when binary encoded (double SHA256).
|
||||
hash util.Uint256
|
||||
|
||||
// Hash of the block used to verify it (single SHA256).
|
||||
verificationHash util.Uint256
|
||||
}
|
||||
|
||||
// baseAux is used to marshal/unmarshal to/from JSON, it's almost the same
|
||||
// as original Base, but with Nonce and NextConsensus fields differing and
|
||||
// Hash added.
|
||||
type baseAux struct {
|
||||
Hash util.Uint256 `json:"hash"`
|
||||
Version uint32 `json:"version"`
|
||||
PrevHash util.Uint256 `json:"previousblockhash"`
|
||||
MerkleRoot util.Uint256 `json:"merkleroot"`
|
||||
Timestamp uint64 `json:"time"`
|
||||
Index uint32 `json:"index"`
|
||||
NextConsensus string `json:"nextconsensus"`
|
||||
PrevStateRoot *util.Uint256 `json:"previousstateroot,omitempty"`
|
||||
Witnesses []transaction.Witness `json:"witnesses"`
|
||||
}
|
||||
|
||||
// Hash returns the hash of the block.
|
||||
func (b *Base) Hash() util.Uint256 {
|
||||
if b.hash.Equals(util.Uint256{}) {
|
||||
b.createHash()
|
||||
}
|
||||
return b.hash
|
||||
}
|
||||
|
||||
// GetSignedHash returns a hash of the block used to verify it.
|
||||
func (b *Base) GetSignedHash() util.Uint256 {
|
||||
if b.verificationHash.Equals(util.Uint256{}) {
|
||||
b.createHash()
|
||||
}
|
||||
return b.verificationHash
|
||||
}
|
||||
|
||||
// DecodeBinary implements Serializable interface.
|
||||
func (b *Base) DecodeBinary(br *io.BinReader) {
|
||||
b.decodeHashableFields(br)
|
||||
witnessCount := br.ReadVarUint()
|
||||
if br.Err == nil && witnessCount != 1 {
|
||||
br.Err = errors.New("wrong witness count")
|
||||
return
|
||||
}
|
||||
|
||||
b.Script.DecodeBinary(br)
|
||||
}
|
||||
|
||||
// EncodeBinary implements Serializable interface
|
||||
func (b *Base) EncodeBinary(bw *io.BinWriter) {
|
||||
b.encodeHashableFields(bw)
|
||||
bw.WriteVarUint(1)
|
||||
b.Script.EncodeBinary(bw)
|
||||
}
|
||||
|
||||
// GetSignedPart returns serialized hashable data of the block.
|
||||
func (b *Base) GetSignedPart() []byte {
|
||||
buf := io.NewBufBinWriter()
|
||||
buf.WriteU32LE(uint32(b.Network))
|
||||
// No error can occure while encoding hashable fields.
|
||||
b.encodeHashableFields(buf.BinWriter)
|
||||
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
// createHash creates the hash of the block.
|
||||
// When calculating the hash value of the block, instead of calculating the entire block,
|
||||
// only first seven fields in the block head will be calculated, which are
|
||||
// version, PrevBlock, MerkleRoot, timestamp, and height, the nonce, NextMiner.
|
||||
// Since MerkleRoot already contains the hash value of all transactions,
|
||||
// the modification of transaction will influence the hash value of the block.
|
||||
func (b *Base) createHash() {
|
||||
bb := b.GetSignedPart()
|
||||
b.verificationHash = hash.Sha256(bb)
|
||||
b.hash = hash.Sha256(b.verificationHash.BytesBE())
|
||||
}
|
||||
|
||||
// encodeHashableFields will only encode the fields used for hashing.
|
||||
// see Hash() for more information about the fields.
|
||||
func (b *Base) encodeHashableFields(bw *io.BinWriter) {
|
||||
bw.WriteU32LE(b.Version)
|
||||
bw.WriteBytes(b.PrevHash[:])
|
||||
bw.WriteBytes(b.MerkleRoot[:])
|
||||
bw.WriteU64LE(b.Timestamp)
|
||||
bw.WriteU32LE(b.Index)
|
||||
bw.WriteBytes(b.NextConsensus[:])
|
||||
if b.StateRootEnabled {
|
||||
bw.WriteBytes(b.PrevStateRoot[:])
|
||||
}
|
||||
}
|
||||
|
||||
// decodeHashableFields decodes the fields used for hashing.
|
||||
// see Hash() for more information about the fields.
|
||||
func (b *Base) decodeHashableFields(br *io.BinReader) {
|
||||
b.Version = br.ReadU32LE()
|
||||
br.ReadBytes(b.PrevHash[:])
|
||||
br.ReadBytes(b.MerkleRoot[:])
|
||||
b.Timestamp = br.ReadU64LE()
|
||||
b.Index = br.ReadU32LE()
|
||||
br.ReadBytes(b.NextConsensus[:])
|
||||
if b.StateRootEnabled {
|
||||
br.ReadBytes(b.PrevStateRoot[:])
|
||||
}
|
||||
|
||||
// Make the hash of the block here so we dont need to do this
|
||||
// again.
|
||||
if br.Err == nil {
|
||||
b.createHash()
|
||||
}
|
||||
}
|
||||
|
||||
// MarshalJSON implements json.Marshaler interface.
|
||||
func (b Base) MarshalJSON() ([]byte, error) {
|
||||
aux := baseAux{
|
||||
Hash: b.Hash(),
|
||||
Version: b.Version,
|
||||
PrevHash: b.PrevHash,
|
||||
MerkleRoot: b.MerkleRoot,
|
||||
Timestamp: b.Timestamp,
|
||||
Index: b.Index,
|
||||
NextConsensus: address.Uint160ToString(b.NextConsensus),
|
||||
Witnesses: []transaction.Witness{b.Script},
|
||||
}
|
||||
if b.StateRootEnabled {
|
||||
aux.PrevStateRoot = &b.PrevStateRoot
|
||||
}
|
||||
return json.Marshal(aux)
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaler interface.
|
||||
func (b *Base) UnmarshalJSON(data []byte) error {
|
||||
var aux = new(baseAux)
|
||||
var nextC util.Uint160
|
||||
|
||||
err := json.Unmarshal(data, aux)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
nextC, err = address.StringToUint160(aux.NextConsensus)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(aux.Witnesses) != 1 {
|
||||
return errors.New("wrong number of witnesses")
|
||||
}
|
||||
b.Version = aux.Version
|
||||
b.PrevHash = aux.PrevHash
|
||||
b.MerkleRoot = aux.MerkleRoot
|
||||
b.Timestamp = aux.Timestamp
|
||||
b.Index = aux.Index
|
||||
b.NextConsensus = nextC
|
||||
b.Script = aux.Witnesses[0]
|
||||
if b.StateRootEnabled {
|
||||
if aux.PrevStateRoot == nil {
|
||||
return errors.New("'previousstateroot' is empty")
|
||||
}
|
||||
b.PrevStateRoot = *aux.PrevStateRoot
|
||||
}
|
||||
if !aux.Hash.Equals(b.Hash()) {
|
||||
return errors.New("json 'hash' doesn't match block hash")
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -67,8 +67,6 @@ func TestTrimmedBlock(t *testing.T) {
|
|||
assert.Equal(t, block.MerkleRoot, trimmedBlock.MerkleRoot)
|
||||
assert.Equal(t, block.Timestamp, trimmedBlock.Timestamp)
|
||||
assert.Equal(t, block.Index, trimmedBlock.Index)
|
||||
require.NoError(t, trimmedBlock.ConsensusData.createHash())
|
||||
assert.Equal(t, block.ConsensusData, trimmedBlock.ConsensusData)
|
||||
assert.Equal(t, block.NextConsensus, trimmedBlock.NextConsensus)
|
||||
|
||||
assert.Equal(t, block.Script, trimmedBlock.Script)
|
||||
|
@ -81,7 +79,7 @@ func TestTrimmedBlock(t *testing.T) {
|
|||
|
||||
func newDumbBlock() *Block {
|
||||
return &Block{
|
||||
Base: Base{
|
||||
Header: Header{
|
||||
Version: 0,
|
||||
PrevHash: hash.Sha256([]byte("a")),
|
||||
MerkleRoot: hash.Sha256([]byte("b")),
|
||||
|
@ -93,10 +91,6 @@ func newDumbBlock() *Block {
|
|||
InvocationScript: []byte{0x61}, // NOP
|
||||
},
|
||||
},
|
||||
ConsensusData: ConsensusData{
|
||||
PrimaryIndex: 0,
|
||||
Nonce: 1111,
|
||||
},
|
||||
Transactions: []*transaction.Transaction{
|
||||
transaction.New(netmode.UnitTestNet, []byte{byte(opcode.PUSH1)}, 0),
|
||||
},
|
||||
|
@ -106,12 +100,12 @@ func newDumbBlock() *Block {
|
|||
func TestHashBlockEqualsHashHeader(t *testing.T) {
|
||||
block := newDumbBlock()
|
||||
|
||||
assert.Equal(t, block.Hash(), block.Header().Hash())
|
||||
assert.Equal(t, block.Hash(), block.Header.Hash())
|
||||
}
|
||||
|
||||
func TestBinBlockDecodeEncode(t *testing.T) {
|
||||
// block taken from testnet: 256
|
||||
rawblock := "AAAAAFIZHAfkJpTDtc9SysVfmBLqDbwXeM7Z7KgaRpWsaCv9qRn3glL7lmCRuSDAE+a5DanThVwfQjtf/1ewuJroTAoqSYJodwEAAAABAADgo8VcrXICj7WQF0ixmie+IfZUBAH9SgEMQBnIhXApbOmC+bxtLNa5UXVrBLRAGC45FHrzZihV+QnTkoYbunP06wsFn38XUEc7tMIhwRxzxKv0BypuietJGgIMQOGFmepNSLy1dhutMGtWPyL1jGXw2toAwgPgMmvJZ0Pq7jY7MAevSh/bupzmeiO6OEt98F+WO4FLJCnJ5BxQ6nIMQBmvuwvPqfhOA0CmTABMZeI/8NnwC6aYAYO3OetbpjxdYeeAHsXSPc0q9RDuXJG3XWtP7M2PPlHm8hsGuzwLaS0MQOA1bTEY/84HwJEddf+X/7S087d2uTIJ12kb08oKDJ3igSFC7xzBtK/hDRXVjR1lwkGjFQHlC6z9T5eWLuNvo4kMQANpdnF0RvnqOViEXigzwjwqe2ETMbDVDul94j3t96FObvxk4ldYjERJOFnMjcPad1XPRFx2vkx4D96ykbonZqj9/QAVDCEDAJt1QOEPJWLl/Y+snq7CUWaliybkEjSP9ahpJ7+sIqIMIQMCBenO+upaHfxYCvIMjVqiRouwFI8aXkYF/GIsgOYEugwhAhS68M7qOmbxfn4eg56iX9i+1s2C5rtuaCUBiQZfRP8BDCECPpsy6om5TQZuZJsST9UOOW7pE2no4qauGxHBcNAiJW0MIQNAjc1BY5b2R4OsWH6h4Vk8V9n+qIDIpqGSDpKiWUd4BgwhAqeDS+mzLimB0VfLW706y0LP0R6lw7ECJNekTpjFkQ8bDCECuixw9ZlvNXpDGYcFhZ+uLP6hPhFyligAdys9WIqdSr0XC0ETje+vAgT7/CQDG7M29gBIg/1LtJSYAAAAAACYPIUAAAAAAH8XAAACV008A99KmydyrwjkspZyEAm3pv0A4KPFXK1yAo+1kBdIsZonviH2VAQBAF8LAwDkC1QCAAAADBT27Zhtj2R4tkfdriCDBpykz9sjQAwU4KPFXK1yAo+1kBdIsZonviH2VAQUwB8MCHRyYW5zZmVyDBQos62rcmn5whgds8t0Hr9VGTDicEFifVtSOQJCDEABqOtwntx2RZGvhG57+6EKkIV3rVc2W1kFk6T4HqWoasBGueGsae057DDLl8LH71OPAPwQUCd1hFSyvt6UzTvvKQwhAqeDS+mzLimB0VfLW706y0LP0R6lw7ECJNekTpjFkQ8bC0GVRA14/UoBDEDiVGE6wrO9dW2QeTKxUnjmKwlKPquQ7/WqLFa1mBYYUndcvXYHasAf5Ir9+JcHeEXEFbPKeIRmjpQ5Zxm222bjDECnQn481SOOOl1Ks7Q2GjeHKvPdi+M2ufHxnwvUly7bh5t4HQxF3GhNp7IguNOZvqGUjB/pJNql7buN8ReJQTBTDECZoVFnkjJgg+UNmdSpdCWzHEKRNpSWiAgWGQhEA+AGXGuldqCkWJ2RFePPcchDxS5Ha2L/Q0nHODiywss59sQ9DECewTwxXkhVA86NHIIbDtQc4/OekUNSlz7I7h/v0CThBucJYQv51QD1bsDnLAnkJ82P0KaL2e87IRduiv2Aqu9xDEAi0z3DIXvkuyIUTZhVLvNfI7HxA2eSS0xr6nHWwoDPKi//FfPJ8jXNViC/MQcJqlPWQD5tL+bQfxPYOAOiwTp//f0AFQwhAwCbdUDhDyVi5f2PrJ6uwlFmpYsm5BI0j/WoaSe/rCKiDCEDAgXpzvrqWh38WAryDI1aokaLsBSPGl5GBfxiLIDmBLoMIQIUuvDO6jpm8X5+HoOeol/YvtbNgua7bmglAYkGX0T/AQwhAj6bMuqJuU0GbmSbEk/VDjlu6RNp6OKmrhsRwXDQIiVtDCEDQI3NQWOW9keDrFh+oeFZPFfZ/qiAyKahkg6SollHeAYMIQKng0vpsy4pgdFXy1u9OstCz9EepcOxAiTXpE6YxZEPGwwhAroscPWZbzV6QxmHBYWfriz+oT4RcpYoAHcrPViKnUq9FwtBE43vrw=="
|
||||
rawblock := "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"
|
||||
rawblockBytes, _ := base64.StdEncoding.DecodeString(rawblock)
|
||||
|
||||
b := New(netmode.TestNet, false)
|
||||
|
@ -147,9 +141,6 @@ func TestBinBlockDecodeEncode(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
assert.Equal(t, rawblock, base64.StdEncoding.EncodeToString(data))
|
||||
|
||||
// update hidden hash value.
|
||||
_ = b.ConsensusData.Hash()
|
||||
|
||||
testserdes.MarshalUnmarshalJSON(t, b, New(netmode.TestNet, false))
|
||||
}
|
||||
|
||||
|
@ -160,7 +151,7 @@ func TestBlockSizeCalculation(t *testing.T) {
|
|||
// should be the same.In this test we provide more details then necessary because in case of failure we can easily debug the
|
||||
// root cause of the size calculation missmatch.
|
||||
|
||||
rawBlock := "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"
|
||||
rawBlock := "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"
|
||||
rawBlockBytes, _ := base64.StdEncoding.DecodeString(rawBlock)
|
||||
|
||||
b := New(netmode.TestNet, false)
|
||||
|
@ -202,19 +193,19 @@ func TestBlockSizeCalculation(t *testing.T) {
|
|||
|
||||
assert.Equal(t, "DEAZyIVwKWzpgvm8bSzWuVF1awS0QBguORR682YoVfkJ05KGG7pz9OsLBZ9/F1BHO7TCIcEcc8Sr9AcqbonrSRoCDEDhhZnqTUi8tXYbrTBrVj8i9Yxl8NraAMID4DJryWdD6u42OzAHr0of27qc5nojujhLffBfljuBSyQpyeQcUOpyDEAZr7sLz6n4TgNApkwATGXiP/DZ8AummAGDtznrW6Y8XWHngB7F0j3NKvUQ7lyRt11rT+zNjz5R5vIbBrs8C2ktDEDgNW0xGP/OB8CRHXX/l/+0tPO3drkyCddpG9PKCgyd4oEhQu8cwbSv4Q0V1Y0dZcJBoxUB5Qus/U+Xli7jb6OJDEADaXZxdEb56jlYhF4oM8I8KnthEzGw1Q7pfeI97fehTm78ZOJXWIxESThZzI3D2ndVz0Rcdr5MeA/espG6J2ao", base64.StdEncoding.EncodeToString(b.Script.InvocationScript))
|
||||
assert.Equal(t, "FQwhAwCbdUDhDyVi5f2PrJ6uwlFmpYsm5BI0j/WoaSe/rCKiDCEDAgXpzvrqWh38WAryDI1aokaLsBSPGl5GBfxiLIDmBLoMIQIUuvDO6jpm8X5+HoOeol/YvtbNgua7bmglAYkGX0T/AQwhAj6bMuqJuU0GbmSbEk/VDjlu6RNp6OKmrhsRwXDQIiVtDCEDQI3NQWOW9keDrFh+oeFZPFfZ/qiAyKahkg6SollHeAYMIQKng0vpsy4pgdFXy1u9OstCz9EepcOxAiTXpE6YxZEPGwwhAroscPWZbzV6QxmHBYWfriz+oT4RcpYoAHcrPViKnUq9FwtBE43vrw==", base64.StdEncoding.EncodeToString(b.Script.VerificationScript))
|
||||
assert.Equal(t, "51ee44e12cdc1d3041a50d352063127fa65d86670686f14cc08f01b3cee7de17", b.Hash().StringLE())
|
||||
assert.Equal(t, "63d18734a3edbe92a9480b690734b85aaf9c24361d034afbea37d749cfc62d6a", b.Hash().StringLE())
|
||||
|
||||
benc, err := testserdes.EncodeBinary(b)
|
||||
assert.NoError(t, err)
|
||||
// test size of the block
|
||||
assert.Equal(t, 1564, len(benc))
|
||||
assert.Equal(t, 1556, len(benc))
|
||||
assert.Equal(t, rawBlock, base64.StdEncoding.EncodeToString(benc))
|
||||
}
|
||||
|
||||
func TestBlockCompare(t *testing.T) {
|
||||
b1 := Block{Base: Base{Index: 1}}
|
||||
b2 := Block{Base: Base{Index: 2}}
|
||||
b3 := Block{Base: Base{Index: 3}}
|
||||
b1 := Block{Header: Header{Index: 1}}
|
||||
b2 := Block{Header: Header{Index: 2}}
|
||||
b3 := Block{Header: Header{Index: 3}}
|
||||
assert.Equal(t, 1, b2.Compare(&b1))
|
||||
assert.Equal(t, 0, b2.Compare(&b2))
|
||||
assert.Equal(t, -1, b2.Compare(&b3))
|
||||
|
@ -230,7 +221,7 @@ func TestBlockEncodeDecode(t *testing.T) {
|
|||
|
||||
t.Run("bad contents count", func(t *testing.T) {
|
||||
b := newDumbBlock()
|
||||
b.Transactions = make([]*transaction.Transaction, MaxContentsPerBlock)
|
||||
b.Transactions = make([]*transaction.Transaction, MaxTransactionsPerBlock+1)
|
||||
for i := range b.Transactions {
|
||||
b.Transactions[i] = &transaction.Transaction{
|
||||
Script: []byte("my_pretty_script"),
|
||||
|
|
|
@ -1,86 +0,0 @@
|
|||
package block
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
)
|
||||
|
||||
// ConsensusData represents primary index and nonce of block in the chain.
|
||||
type ConsensusData struct {
|
||||
// Primary index
|
||||
PrimaryIndex uint32
|
||||
// Random number
|
||||
Nonce uint64
|
||||
// Hash of the ConsensusData (single SHA256)
|
||||
hash util.Uint256
|
||||
}
|
||||
|
||||
// jsonConsensusData is used for JSON I/O of ConsensusData.
|
||||
type jsonConsensusData struct {
|
||||
Primary uint32 `json:"primary"`
|
||||
Nonce string `json:"nonce"`
|
||||
}
|
||||
|
||||
// DecodeBinary implements Serializable interface.
|
||||
func (c *ConsensusData) DecodeBinary(br *io.BinReader) {
|
||||
c.PrimaryIndex = uint32(br.ReadVarUint())
|
||||
c.Nonce = br.ReadU64LE()
|
||||
}
|
||||
|
||||
// EncodeBinary encodes implements Serializable interface.
|
||||
func (c *ConsensusData) EncodeBinary(bw *io.BinWriter) {
|
||||
bw.WriteVarUint(uint64(c.PrimaryIndex))
|
||||
bw.WriteU64LE(c.Nonce)
|
||||
}
|
||||
|
||||
// Hash returns the hash of the consensus data.
|
||||
func (c *ConsensusData) Hash() util.Uint256 {
|
||||
if c.hash.Equals(util.Uint256{}) {
|
||||
if c.createHash() != nil {
|
||||
panic("failed to compute hash!")
|
||||
}
|
||||
}
|
||||
return c.hash
|
||||
}
|
||||
|
||||
// createHash creates the hash of the consensus data.
|
||||
func (c *ConsensusData) createHash() error {
|
||||
buf := io.NewBufBinWriter()
|
||||
c.EncodeBinary(buf.BinWriter)
|
||||
if buf.Err != nil {
|
||||
return buf.Err
|
||||
}
|
||||
|
||||
b := buf.Bytes()
|
||||
c.hash = hash.DoubleSha256(b)
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON implements json.Marshaler interface.
|
||||
func (c ConsensusData) MarshalJSON() ([]byte, error) {
|
||||
nonce := strconv.FormatUint(c.Nonce, 16)
|
||||
for len(nonce) < 16 {
|
||||
nonce = "0" + nonce
|
||||
}
|
||||
return json.Marshal(jsonConsensusData{Primary: c.PrimaryIndex, Nonce: nonce})
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaler interface.
|
||||
func (c *ConsensusData) UnmarshalJSON(data []byte) error {
|
||||
jcd := new(jsonConsensusData)
|
||||
err := json.Unmarshal(data, jcd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
nonce, err := strconv.ParseUint(jcd.Nonce, 16, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.PrimaryIndex = jcd.Primary
|
||||
c.Nonce = nonce
|
||||
return nil
|
||||
}
|
|
@ -1,31 +1,223 @@
|
|||
package block
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
)
|
||||
|
||||
// Header holds the head info of a block.
|
||||
// Header holds the base info of a block
|
||||
type Header struct {
|
||||
// Base of the block.
|
||||
Base
|
||||
// Version of the block.
|
||||
Version uint32
|
||||
|
||||
// hash of the previous block.
|
||||
PrevHash util.Uint256
|
||||
|
||||
// Root hash of a transaction list.
|
||||
MerkleRoot util.Uint256
|
||||
|
||||
// Timestamp is a millisecond-precision timestamp.
|
||||
// The time stamp of each block must be later than previous block's time stamp.
|
||||
// Generally the difference of two block's time stamp is about 15 seconds and imprecision is allowed.
|
||||
// The height of the block must be exactly equal to the height of the previous block plus 1.
|
||||
Timestamp uint64
|
||||
|
||||
// index/height of the block
|
||||
Index uint32
|
||||
|
||||
// Contract address of the next miner
|
||||
NextConsensus util.Uint160
|
||||
|
||||
// Script used to validate the block
|
||||
Script transaction.Witness
|
||||
|
||||
// Network magic number this block belongs to. This one actually is not
|
||||
// a part of the wire-representation of Block, but it's absolutely
|
||||
// necessary for correct signing/verification.
|
||||
Network netmode.Magic
|
||||
|
||||
// StateRootEnabled specifies if header contains state root.
|
||||
StateRootEnabled bool
|
||||
// PrevStateRoot is state root of the previous block.
|
||||
PrevStateRoot util.Uint256
|
||||
// PrimaryIndex is the index of primary consensus node for this block.
|
||||
PrimaryIndex byte
|
||||
|
||||
// Hash of this block, created when binary encoded (double SHA256).
|
||||
hash util.Uint256
|
||||
|
||||
// Hash of the block used to verify it (single SHA256).
|
||||
verificationHash util.Uint256
|
||||
}
|
||||
|
||||
// baseAux is used to marshal/unmarshal to/from JSON, it's almost the same
|
||||
// as original Base, but with Nonce and NextConsensus fields differing and
|
||||
// Hash added.
|
||||
type baseAux struct {
|
||||
Hash util.Uint256 `json:"hash"`
|
||||
Version uint32 `json:"version"`
|
||||
PrevHash util.Uint256 `json:"previousblockhash"`
|
||||
MerkleRoot util.Uint256 `json:"merkleroot"`
|
||||
Timestamp uint64 `json:"time"`
|
||||
Index uint32 `json:"index"`
|
||||
NextConsensus string `json:"nextconsensus"`
|
||||
PrimaryIndex byte `json:"primary"`
|
||||
PrevStateRoot *util.Uint256 `json:"previousstateroot,omitempty"`
|
||||
Witnesses []transaction.Witness `json:"witnesses"`
|
||||
}
|
||||
|
||||
// Hash returns the hash of the block.
|
||||
func (b *Header) Hash() util.Uint256 {
|
||||
if b.hash.Equals(util.Uint256{}) {
|
||||
b.createHash()
|
||||
}
|
||||
return b.hash
|
||||
}
|
||||
|
||||
// GetSignedHash returns a hash of the block used to verify it.
|
||||
func (b *Header) GetSignedHash() util.Uint256 {
|
||||
if b.verificationHash.Equals(util.Uint256{}) {
|
||||
b.createHash()
|
||||
}
|
||||
return b.verificationHash
|
||||
}
|
||||
|
||||
// DecodeBinary implements Serializable interface.
|
||||
func (h *Header) DecodeBinary(r *io.BinReader) {
|
||||
h.Base.DecodeBinary(r)
|
||||
func (b *Header) DecodeBinary(br *io.BinReader) {
|
||||
b.decodeHashableFields(br)
|
||||
witnessCount := br.ReadVarUint()
|
||||
if br.Err == nil && witnessCount != 1 {
|
||||
br.Err = errors.New("wrong witness count")
|
||||
return
|
||||
}
|
||||
|
||||
padding := []byte{0}
|
||||
r.ReadBytes(padding)
|
||||
b.Script.DecodeBinary(br)
|
||||
}
|
||||
|
||||
if padding[0] != 0 {
|
||||
r.Err = fmt.Errorf("format error: padding must equal 0 got %d", padding)
|
||||
// EncodeBinary implements Serializable interface
|
||||
func (b *Header) EncodeBinary(bw *io.BinWriter) {
|
||||
b.encodeHashableFields(bw)
|
||||
bw.WriteVarUint(1)
|
||||
b.Script.EncodeBinary(bw)
|
||||
}
|
||||
|
||||
// GetSignedPart returns serialized hashable data of the block.
|
||||
func (b *Header) GetSignedPart() []byte {
|
||||
buf := io.NewBufBinWriter()
|
||||
buf.WriteU32LE(uint32(b.Network))
|
||||
// No error can occure while encoding hashable fields.
|
||||
b.encodeHashableFields(buf.BinWriter)
|
||||
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
// createHash creates the hash of the block.
|
||||
// When calculating the hash value of the block, instead of calculating the entire block,
|
||||
// only first seven fields in the block head will be calculated, which are
|
||||
// version, PrevBlock, MerkleRoot, timestamp, and height, the nonce, NextMiner.
|
||||
// Since MerkleRoot already contains the hash value of all transactions,
|
||||
// the modification of transaction will influence the hash value of the block.
|
||||
func (b *Header) createHash() {
|
||||
bb := b.GetSignedPart()
|
||||
b.verificationHash = hash.Sha256(bb)
|
||||
b.hash = hash.Sha256(b.verificationHash.BytesBE())
|
||||
}
|
||||
|
||||
// encodeHashableFields will only encode the fields used for hashing.
|
||||
// see Hash() for more information about the fields.
|
||||
func (b *Header) encodeHashableFields(bw *io.BinWriter) {
|
||||
bw.WriteU32LE(b.Version)
|
||||
bw.WriteBytes(b.PrevHash[:])
|
||||
bw.WriteBytes(b.MerkleRoot[:])
|
||||
bw.WriteU64LE(b.Timestamp)
|
||||
bw.WriteU32LE(b.Index)
|
||||
bw.WriteB(b.PrimaryIndex)
|
||||
bw.WriteBytes(b.NextConsensus[:])
|
||||
if b.StateRootEnabled {
|
||||
bw.WriteBytes(b.PrevStateRoot[:])
|
||||
}
|
||||
}
|
||||
|
||||
// EncodeBinary implements Serializable interface.
|
||||
func (h *Header) EncodeBinary(w *io.BinWriter) {
|
||||
h.Base.EncodeBinary(w)
|
||||
w.WriteBytes([]byte{0})
|
||||
// decodeHashableFields decodes the fields used for hashing.
|
||||
// see Hash() for more information about the fields.
|
||||
func (b *Header) decodeHashableFields(br *io.BinReader) {
|
||||
b.Version = br.ReadU32LE()
|
||||
br.ReadBytes(b.PrevHash[:])
|
||||
br.ReadBytes(b.MerkleRoot[:])
|
||||
b.Timestamp = br.ReadU64LE()
|
||||
b.Index = br.ReadU32LE()
|
||||
b.PrimaryIndex = br.ReadB()
|
||||
br.ReadBytes(b.NextConsensus[:])
|
||||
if b.StateRootEnabled {
|
||||
br.ReadBytes(b.PrevStateRoot[:])
|
||||
}
|
||||
|
||||
// Make the hash of the block here so we dont need to do this
|
||||
// again.
|
||||
if br.Err == nil {
|
||||
b.createHash()
|
||||
}
|
||||
}
|
||||
|
||||
// MarshalJSON implements json.Marshaler interface.
|
||||
func (b Header) MarshalJSON() ([]byte, error) {
|
||||
aux := baseAux{
|
||||
Hash: b.Hash(),
|
||||
Version: b.Version,
|
||||
PrevHash: b.PrevHash,
|
||||
MerkleRoot: b.MerkleRoot,
|
||||
Timestamp: b.Timestamp,
|
||||
Index: b.Index,
|
||||
PrimaryIndex: b.PrimaryIndex,
|
||||
NextConsensus: address.Uint160ToString(b.NextConsensus),
|
||||
Witnesses: []transaction.Witness{b.Script},
|
||||
}
|
||||
if b.StateRootEnabled {
|
||||
aux.PrevStateRoot = &b.PrevStateRoot
|
||||
}
|
||||
return json.Marshal(aux)
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaler interface.
|
||||
func (b *Header) UnmarshalJSON(data []byte) error {
|
||||
var aux = new(baseAux)
|
||||
var nextC util.Uint160
|
||||
|
||||
err := json.Unmarshal(data, aux)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
nextC, err = address.StringToUint160(aux.NextConsensus)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(aux.Witnesses) != 1 {
|
||||
return errors.New("wrong number of witnesses")
|
||||
}
|
||||
b.Version = aux.Version
|
||||
b.PrevHash = aux.PrevHash
|
||||
b.MerkleRoot = aux.MerkleRoot
|
||||
b.Timestamp = aux.Timestamp
|
||||
b.Index = aux.Index
|
||||
b.PrimaryIndex = aux.PrimaryIndex
|
||||
b.NextConsensus = nextC
|
||||
b.Script = aux.Witnesses[0]
|
||||
if b.StateRootEnabled {
|
||||
if aux.PrevStateRoot == nil {
|
||||
return errors.New("'previousstateroot' is empty")
|
||||
}
|
||||
b.PrevStateRoot = *aux.PrevStateRoot
|
||||
}
|
||||
if !aux.Hash.Equals(b.Hash()) {
|
||||
return errors.New("json 'hash' doesn't match block hash")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ import (
|
|||
)
|
||||
|
||||
func testHeaderEncodeDecode(t *testing.T, stateRootEnabled bool) {
|
||||
header := Header{Base: Base{
|
||||
header := Header{
|
||||
Version: 0,
|
||||
PrevHash: hash.Sha256([]byte("prevhash")),
|
||||
MerkleRoot: hash.Sha256([]byte("merkleroot")),
|
||||
|
@ -24,14 +24,14 @@ func testHeaderEncodeDecode(t *testing.T, stateRootEnabled bool) {
|
|||
InvocationScript: []byte{0x10},
|
||||
VerificationScript: []byte{0x11},
|
||||
},
|
||||
}}
|
||||
}
|
||||
if stateRootEnabled {
|
||||
header.StateRootEnabled = stateRootEnabled
|
||||
header.PrevStateRoot = random.Uint256()
|
||||
}
|
||||
|
||||
_ = header.Hash()
|
||||
headerDecode := &Header{Base: Base{StateRootEnabled: stateRootEnabled}}
|
||||
headerDecode := &Header{StateRootEnabled: stateRootEnabled}
|
||||
testserdes.EncodeDecodeBinary(t, &header, headerDecode)
|
||||
|
||||
assert.Equal(t, header.Version, headerDecode.Version, "expected both versions to be equal")
|
||||
|
|
|
@ -491,7 +491,7 @@ func (bc *Blockchain) AddBlock(block *block.Block) error {
|
|||
}
|
||||
|
||||
if block.Index == bc.HeaderHeight()+1 {
|
||||
err := bc.addHeaders(bc.config.VerifyBlocks, block.Header())
|
||||
err := bc.addHeaders(bc.config.VerifyBlocks, &block.Header)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -576,6 +576,7 @@ func (bc *Blockchain) addHeaders(verify bool, headers ...*block.Header) error {
|
|||
}
|
||||
bc.headerHashes = append(bc.headerHashes, h.Hash())
|
||||
h.EncodeBinary(buf.BinWriter)
|
||||
buf.BinWriter.WriteB(0)
|
||||
if buf.Err != nil {
|
||||
return buf.Err
|
||||
}
|
||||
|
@ -1121,6 +1122,9 @@ func (bc *Blockchain) GetBlock(hash util.Uint256) (*block.Block, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !block.MerkleRoot.Equals(util.Uint256{}) && len(block.Transactions) == 0 {
|
||||
return nil, errors.New("only header is found")
|
||||
}
|
||||
for _, tx := range block.Transactions {
|
||||
stx, _, err := bc.dao.GetTransaction(tx.Hash())
|
||||
if err != nil {
|
||||
|
@ -1137,14 +1141,14 @@ func (bc *Blockchain) GetHeader(hash util.Uint256) (*block.Header, error) {
|
|||
if topBlock != nil {
|
||||
tb := topBlock.(*block.Block)
|
||||
if tb.Hash().Equals(hash) {
|
||||
return tb.Header(), nil
|
||||
return &tb.Header, nil
|
||||
}
|
||||
}
|
||||
block, err := bc.dao.GetBlock(hash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return block.Header(), nil
|
||||
return &block.Header, nil
|
||||
}
|
||||
|
||||
// HasTransaction returns true if the blockchain contains he given
|
||||
|
|
|
@ -42,63 +42,63 @@ import (
|
|||
|
||||
func TestVerifyHeader(t *testing.T) {
|
||||
bc := newTestChain(t)
|
||||
prev := bc.topBlock.Load().(*block.Block).Header()
|
||||
prev := bc.topBlock.Load().(*block.Block).Header
|
||||
t.Run("Invalid", func(t *testing.T) {
|
||||
t.Run("Hash", func(t *testing.T) {
|
||||
h := prev.Hash()
|
||||
h[0] = ^h[0]
|
||||
hdr := newBlock(bc.config, 1, h).Header()
|
||||
require.True(t, errors.Is(bc.verifyHeader(hdr, prev), ErrHdrHashMismatch))
|
||||
hdr := newBlock(bc.config, 1, h).Header
|
||||
require.True(t, errors.Is(bc.verifyHeader(&hdr, &prev), ErrHdrHashMismatch))
|
||||
})
|
||||
t.Run("Index", func(t *testing.T) {
|
||||
hdr := newBlock(bc.config, 3, prev.Hash()).Header()
|
||||
require.True(t, errors.Is(bc.verifyHeader(hdr, prev), ErrHdrIndexMismatch))
|
||||
hdr := newBlock(bc.config, 3, prev.Hash()).Header
|
||||
require.True(t, errors.Is(bc.verifyHeader(&hdr, &prev), ErrHdrIndexMismatch))
|
||||
})
|
||||
t.Run("Timestamp", func(t *testing.T) {
|
||||
hdr := newBlock(bc.config, 1, prev.Hash()).Header()
|
||||
hdr := newBlock(bc.config, 1, prev.Hash()).Header
|
||||
hdr.Timestamp = 0
|
||||
require.True(t, errors.Is(bc.verifyHeader(hdr, prev), ErrHdrInvalidTimestamp))
|
||||
require.True(t, errors.Is(bc.verifyHeader(&hdr, &prev), ErrHdrInvalidTimestamp))
|
||||
})
|
||||
})
|
||||
t.Run("Valid", func(t *testing.T) {
|
||||
hdr := newBlock(bc.config, 1, prev.Hash()).Header()
|
||||
require.NoError(t, bc.verifyHeader(hdr, prev))
|
||||
hdr := newBlock(bc.config, 1, prev.Hash()).Header
|
||||
require.NoError(t, bc.verifyHeader(&hdr, &prev))
|
||||
})
|
||||
}
|
||||
|
||||
func TestAddHeaders(t *testing.T) {
|
||||
bc := newTestChain(t)
|
||||
lastBlock := bc.topBlock.Load().(*block.Block)
|
||||
h1 := newBlock(bc.config, 1, lastBlock.Hash()).Header()
|
||||
h2 := newBlock(bc.config, 2, h1.Hash()).Header()
|
||||
h3 := newBlock(bc.config, 3, h2.Hash()).Header()
|
||||
h1 := newBlock(bc.config, 1, lastBlock.Hash()).Header
|
||||
h2 := newBlock(bc.config, 2, h1.Hash()).Header
|
||||
h3 := newBlock(bc.config, 3, h2.Hash()).Header
|
||||
|
||||
require.NoError(t, bc.AddHeaders())
|
||||
require.NoError(t, bc.AddHeaders(h1, h2))
|
||||
require.NoError(t, bc.AddHeaders(h2, h3))
|
||||
require.NoError(t, bc.AddHeaders(&h1, &h2))
|
||||
require.NoError(t, bc.AddHeaders(&h2, &h3))
|
||||
|
||||
assert.Equal(t, h3.Index, bc.HeaderHeight())
|
||||
assert.Equal(t, uint32(0), bc.BlockHeight())
|
||||
assert.Equal(t, h3.Hash(), bc.CurrentHeaderHash())
|
||||
|
||||
// Add them again, they should not be added.
|
||||
require.NoError(t, bc.AddHeaders(h3, h2, h1))
|
||||
require.NoError(t, bc.AddHeaders(&h3, &h2, &h1))
|
||||
|
||||
assert.Equal(t, h3.Index, bc.HeaderHeight())
|
||||
assert.Equal(t, uint32(0), bc.BlockHeight())
|
||||
assert.Equal(t, h3.Hash(), bc.CurrentHeaderHash())
|
||||
|
||||
h4 := newBlock(bc.config, 4, h3.Hash().Reverse()).Header()
|
||||
h5 := newBlock(bc.config, 5, h4.Hash()).Header()
|
||||
h4 := newBlock(bc.config, 4, h3.Hash().Reverse()).Header
|
||||
h5 := newBlock(bc.config, 5, h4.Hash()).Header
|
||||
|
||||
assert.Error(t, bc.AddHeaders(h4, h5))
|
||||
assert.Error(t, bc.AddHeaders(&h4, &h5))
|
||||
assert.Equal(t, h3.Index, bc.HeaderHeight())
|
||||
assert.Equal(t, uint32(0), bc.BlockHeight())
|
||||
assert.Equal(t, h3.Hash(), bc.CurrentHeaderHash())
|
||||
|
||||
h6 := newBlock(bc.config, 4, h3.Hash()).Header()
|
||||
h6 := newBlock(bc.config, 4, h3.Hash()).Header
|
||||
h6.Script.InvocationScript = nil
|
||||
assert.Error(t, bc.AddHeaders(h6))
|
||||
assert.Error(t, bc.AddHeaders(&h6))
|
||||
assert.Equal(t, h3.Index, bc.HeaderHeight())
|
||||
assert.Equal(t, uint32(0), bc.BlockHeight())
|
||||
assert.Equal(t, h3.Hash(), bc.CurrentHeaderHash())
|
||||
|
@ -206,7 +206,7 @@ func TestGetHeader(t *testing.T) {
|
|||
hash := block.Hash()
|
||||
header, err := bc.GetHeader(hash)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, block.Header(), header)
|
||||
assert.Equal(t, &block.Header, header)
|
||||
|
||||
b2 := bc.newBlock()
|
||||
_, err = bc.GetHeader(b2.Hash())
|
||||
|
@ -230,6 +230,33 @@ func TestGetBlock(t *testing.T) {
|
|||
}
|
||||
assert.NoError(t, bc.persist())
|
||||
}
|
||||
|
||||
t.Run("store only header", func(t *testing.T) {
|
||||
t.Run("non-empty block", func(t *testing.T) {
|
||||
tx, err := testchain.NewTransferFromOwner(bc, bc.contracts.NEO.Hash,
|
||||
random.Uint160(), 1, 1, 1000)
|
||||
b := bc.newBlock(tx)
|
||||
require.NoError(t, bc.AddHeaders(&b.Header))
|
||||
|
||||
_, err = bc.GetBlock(b.Hash())
|
||||
require.Error(t, err)
|
||||
|
||||
_, err = bc.GetHeader(b.Hash())
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NoError(t, bc.AddBlock(b))
|
||||
|
||||
_, err = bc.GetBlock(b.Hash())
|
||||
require.NoError(t, err)
|
||||
})
|
||||
t.Run("empty block", func(t *testing.T) {
|
||||
b := bc.newBlock()
|
||||
require.NoError(t, bc.AddHeaders(&b.Header))
|
||||
|
||||
_, err = bc.GetBlock(b.Hash())
|
||||
require.NoError(t, err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func (bc *Blockchain) newTestTx(h util.Uint160, script []byte) *transaction.Transaction {
|
||||
|
@ -1558,9 +1585,10 @@ func TestRemoveUntraceable(t *testing.T) {
|
|||
require.Error(t, err)
|
||||
_, err = bc.GetAppExecResults(tx1.Hash(), trigger.Application)
|
||||
require.Error(t, err)
|
||||
b, err := bc.GetBlock(b1.Hash())
|
||||
_, err = bc.GetBlock(b1.Hash())
|
||||
require.Error(t, err)
|
||||
_, err = bc.GetHeader(b1.Hash())
|
||||
require.NoError(t, err)
|
||||
require.Len(t, b.Transactions, 0)
|
||||
}
|
||||
|
||||
func TestInvalidNotification(t *testing.T) {
|
||||
|
|
|
@ -538,7 +538,8 @@ func (dao *Simple) DeleteBlock(h util.Uint256, w *io.BufBinWriter) error {
|
|||
if w == nil {
|
||||
w = io.NewBufBinWriter()
|
||||
}
|
||||
b.Header().EncodeBinary(w.BinWriter)
|
||||
b.Header.EncodeBinary(w.BinWriter)
|
||||
w.BinWriter.WriteB(0)
|
||||
if w.Err != nil {
|
||||
return w.Err
|
||||
}
|
||||
|
|
|
@ -95,7 +95,7 @@ func TestGetBlock_NotExists(t *testing.T) {
|
|||
func TestPutGetBlock(t *testing.T) {
|
||||
dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet, false)
|
||||
b := &block.Block{
|
||||
Base: block.Base{
|
||||
Header: block.Header{
|
||||
Script: transaction.Witness{
|
||||
VerificationScript: []byte{byte(opcode.PUSH1)},
|
||||
InvocationScript: []byte{byte(opcode.NOP)},
|
||||
|
@ -136,7 +136,7 @@ func TestGetCurrentHeaderHeight_NoHeader(t *testing.T) {
|
|||
func TestGetCurrentHeaderHeight_Store(t *testing.T) {
|
||||
dao := NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet, false)
|
||||
b := &block.Block{
|
||||
Base: block.Base{
|
||||
Header: block.Header{
|
||||
Script: transaction.Witness{
|
||||
VerificationScript: []byte{byte(opcode.PUSH1)},
|
||||
InvocationScript: []byte{byte(opcode.NOP)},
|
||||
|
|
|
@ -108,15 +108,11 @@ func newBlockCustom(cfg config.ProtocolConfiguration, f func(b *block.Block),
|
|||
VerificationScript: valScript,
|
||||
}
|
||||
b := &block.Block{
|
||||
Base: block.Base{
|
||||
Header: block.Header{
|
||||
Network: testchain.Network(),
|
||||
NextConsensus: witness.ScriptHash(),
|
||||
Script: witness,
|
||||
},
|
||||
ConsensusData: block.ConsensusData{
|
||||
PrimaryIndex: 0,
|
||||
Nonce: 1111,
|
||||
},
|
||||
Transactions: txs,
|
||||
}
|
||||
f(b)
|
||||
|
@ -209,7 +205,7 @@ func getBlockData(i int) (map[string]interface{}, error) {
|
|||
|
||||
func newDumbBlock() *block.Block {
|
||||
return &block.Block{
|
||||
Base: block.Base{
|
||||
Header: block.Header{
|
||||
Network: testchain.Network(),
|
||||
Version: 0,
|
||||
PrevHash: hash.Sha256([]byte("a")),
|
||||
|
@ -222,10 +218,6 @@ func newDumbBlock() *block.Block {
|
|||
InvocationScript: []byte{0x61}, // NOP
|
||||
},
|
||||
},
|
||||
ConsensusData: block.ConsensusData{
|
||||
PrimaryIndex: 0,
|
||||
Nonce: 1111,
|
||||
},
|
||||
Transactions: []*transaction.Transaction{
|
||||
transaction.New(testchain.Network(), []byte{byte(opcode.PUSH1)}, 0),
|
||||
},
|
||||
|
@ -333,7 +325,7 @@ func initBasicChain(t *testing.T, bc *Blockchain) {
|
|||
// info for getblockheader rpc tests
|
||||
t.Logf("header hash: %s", b.Hash().StringLE())
|
||||
buf := io.NewBufBinWriter()
|
||||
b.Header().EncodeBinary(buf.BinWriter)
|
||||
b.Header.EncodeBinary(buf.BinWriter)
|
||||
t.Logf("header: %s", hex.EncodeToString(buf.Bytes()))
|
||||
|
||||
acc0 := wallet.NewAccountFromPrivateKey(priv0)
|
||||
|
|
|
@ -92,7 +92,6 @@ func Log(ic *interop.Context) error {
|
|||
// GetTime returns timestamp of the block being verified, or the latest
|
||||
// one in the blockchain if no block is given to Context.
|
||||
func GetTime(ic *interop.Context) error {
|
||||
header := ic.Block.Header()
|
||||
ic.VM.Estack().PushVal(header.Timestamp)
|
||||
ic.VM.Estack().PushVal(ic.Block.Timestamp)
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -85,7 +85,7 @@ func (g *GAS) OnPersist(ic *interop.Context) error {
|
|||
g.burn(ic, tx.Sender(), absAmount)
|
||||
}
|
||||
validators := g.NEO.GetNextBlockValidatorsInternal()
|
||||
primary := validators[ic.Block.ConsensusData.PrimaryIndex].GetScriptHash()
|
||||
primary := validators[ic.Block.PrimaryIndex].GetScriptHash()
|
||||
var netFee int64
|
||||
for _, tx := range ic.Block.Transactions {
|
||||
netFee += tx.NetworkFee
|
||||
|
|
|
@ -1,16 +1,13 @@
|
|||
{
|
||||
"raw": "0000000052191c07e42694c3b5cf52cac55f9812ea0dbc1778ced9eca81a4695ac682bfda919f78252fb966091b920c013e6b90da9d3855c1f423b5fff57b0b89ae84c0a2a4982687701000000010000e0a3c55cad72028fb5901748b19a27be21f6540401fd4a010c4019c88570296ce982f9bc6d2cd6b951756b04b440182e39147af3662855f909d392861bba73f4eb0b059f7f1750473bb4c221c11c73c4abf4072a6e89eb491a020c40e18599ea4d48bcb5761bad306b563f22f58c65f0dada00c203e0326bc96743eaee363b3007af4a1fdbba9ce67a23ba384b7df05f963b814b2429c9e41c50ea720c4019afbb0bcfa9f84e0340a64c004c65e23ff0d9f00ba6980183b739eb5ba63c5d61e7801ec5d23dcd2af510ee5c91b75d6b4feccd8f3e51e6f21b06bb3c0b692d0c40e0356d3118ffce07c0911d75ff97ffb4b4f3b776b93209d7691bd3ca0a0c9de2812142ef1cc1b4afe10d15d58d1d65c241a31501e50bacfd4f97962ee36fa3890c40036976717446f9ea3958845e2833c23c2a7b611331b0d50ee97de23dedf7a14e6efc64e257588c44493859cc8dc3da7755cf445c76be4c780fdeb291ba2766a8fdfd00150c2103009b7540e10f2562e5fd8fac9eaec25166a58b26e412348ff5a86927bfac22a20c21030205e9cefaea5a1dfc580af20c8d5aa2468bb0148f1a5e4605fc622c80e604ba0c210214baf0ceea3a66f17e7e1e839ea25fd8bed6cd82e6bb6e68250189065f44ff010c21023e9b32ea89b94d066e649b124fd50e396ee91369e8e2a6ae1b11c170d022256d0c2103408dcd416396f64783ac587ea1e1593c57d9fea880c8a6a1920e92a2594778060c2102a7834be9b32e2981d157cb5bbd3acb42cfd11ea5c3b10224d7a44e98c5910f1b0c2102ba2c70f5996f357a43198705859fae2cfea13e1172962800772b3d588a9d4abd170b41138defaf0204fbfc24031bb336f6004883fd4bb494980000000000983c8500000000007f17000002574d3c03df4a9b2772af08e4b296721009b7a6fd00e0a3c55cad72028fb5901748b19a27be21f6540401005f0b0300e40b54020000000c14f6ed986d8f6478b647ddae2083069ca4cfdb23400c14e0a3c55cad72028fb5901748b19a27be21f6540414c01f0c087472616e736665720c1428b3adab7269f9c2181db3cb741ebf551930e27041627d5b523902420c4001a8eb709edc764591af846e7bfba10a908577ad57365b590593a4f81ea5a86ac046b9e1ac69ed39ec30cb97c2c7ef538f00fc105027758454b2bede94cd3bef290c2102a7834be9b32e2981d157cb5bbd3acb42cfd11ea5c3b10224d7a44e98c5910f1b0b4195440d78fd4a010c40e254613ac2b3bd756d907932b15278e62b094a3eab90eff5aa2c56b598161852775cbd76076ac01fe48afdf897077845c415b3ca7884668e94396719b6db66e30c40a7427e3cd5238e3a5d4ab3b4361a37872af3dd8be336b9f1f19f0bd4972edb879b781d0c45dc684da7b220b8d399bea1948c1fe924daa5edbb8df117894130530c4099a1516792326083e50d99d4a97425b31c429136949688081619084403e0065c6ba576a0a4589d9115e3cf71c843c52e476b62ff4349c73838b2c2cb39f6c43d0c409ec13c315e485503ce8d1c821b0ed41ce3f39e914352973ec8ee1fefd024e106e709610bf9d500f56ec0e72c09e427cd8fd0a68bd9ef3b21176e8afd80aaef710c4022d33dc3217be4bb22144d98552ef35f23b1f10367924b4c6bea71d6c280cf2a2fff15f3c9f235cd5620bf310709aa53d6403e6d2fe6d07f13d83803a2c13a7ffdfd00150c2103009b7540e10f2562e5fd8fac9eaec25166a58b26e412348ff5a86927bfac22a20c21030205e9cefaea5a1dfc580af20c8d5aa2468bb0148f1a5e4605fc622c80e604ba0c210214baf0ceea3a66f17e7e1e839ea25fd8bed6cd82e6bb6e68250189065f44ff010c21023e9b32ea89b94d066e649b124fd50e396ee91369e8e2a6ae1b11c170d022256d0c2103408dcd416396f64783ac587ea1e1593c57d9fea880c8a6a1920e92a2594778060c2102a7834be9b32e2981d157cb5bbd3acb42cfd11ea5c3b10224d7a44e98c5910f1b0c2102ba2c70f5996f357a43198705859fae2cfea13e1172962800772b3d588a9d4abd170b41138defaf",
|
||||
"raw": "0000000052191c07e42694c3b5cf52cac55f9812ea0dbc1778ced9eca81a4695ac682bfda919f78252fb966091b920c013e6b90da9d3855c1f423b5fff57b0b89ae84c0a2a498268770100000001000004e0a3c55cad72028fb5901748b19a27be21f6540401fd4a010c4019c88570296ce982f9bc6d2cd6b951756b04b440182e39147af3662855f909d392861bba73f4eb0b059f7f1750473bb4c221c11c73c4abf4072a6e89eb491a020c40e18599ea4d48bcb5761bad306b563f22f58c65f0dada00c203e0326bc96743eaee363b3007af4a1fdbba9ce67a23ba384b7df05f963b814b2429c9e41c50ea720c4019afbb0bcfa9f84e0340a64c004c65e23ff0d9f00ba6980183b739eb5ba63c5d61e7801ec5d23dcd2af510ee5c91b75d6b4feccd8f3e51e6f21b06bb3c0b692d0c40e0356d3118ffce07c0911d75ff97ffb4b4f3b776b93209d7691bd3ca0a0c9de2812142ef1cc1b4afe10d15d58d1d65c241a31501e50bacfd4f97962ee36fa3890c40036976717446f9ea3958845e2833c23c2a7b611331b0d50ee97de23dedf7a14e6efc64e257588c44493859cc8dc3da7755cf445c76be4c780fdeb291ba2766a8fdfd00150c2103009b7540e10f2562e5fd8fac9eaec25166a58b26e412348ff5a86927bfac22a20c21030205e9cefaea5a1dfc580af20c8d5aa2468bb0148f1a5e4605fc622c80e604ba0c210214baf0ceea3a66f17e7e1e839ea25fd8bed6cd82e6bb6e68250189065f44ff010c21023e9b32ea89b94d066e649b124fd50e396ee91369e8e2a6ae1b11c170d022256d0c2103408dcd416396f64783ac587ea1e1593c57d9fea880c8a6a1920e92a2594778060c2102a7834be9b32e2981d157cb5bbd3acb42cfd11ea5c3b10224d7a44e98c5910f1b0c2102ba2c70f5996f357a43198705859fae2cfea13e1172962800772b3d588a9d4abd170b41138defaf01004883fd4bb494980000000000983c8500000000007f17000002574d3c03df4a9b2772af08e4b296721009b7a6fd00e0a3c55cad72028fb5901748b19a27be21f6540401005f0b0300e40b54020000000c14f6ed986d8f6478b647ddae2083069ca4cfdb23400c14e0a3c55cad72028fb5901748b19a27be21f6540414c01f0c087472616e736665720c1428b3adab7269f9c2181db3cb741ebf551930e27041627d5b523902420c4001a8eb709edc764591af846e7bfba10a908577ad57365b590593a4f81ea5a86ac046b9e1ac69ed39ec30cb97c2c7ef538f00fc105027758454b2bede94cd3bef290c2102a7834be9b32e2981d157cb5bbd3acb42cfd11ea5c3b10224d7a44e98c5910f1b0b4195440d78fd4a010c40e254613ac2b3bd756d907932b15278e62b094a3eab90eff5aa2c56b598161852775cbd76076ac01fe48afdf897077845c415b3ca7884668e94396719b6db66e30c40a7427e3cd5238e3a5d4ab3b4361a37872af3dd8be336b9f1f19f0bd4972edb879b781d0c45dc684da7b220b8d399bea1948c1fe924daa5edbb8df117894130530c4099a1516792326083e50d99d4a97425b31c429136949688081619084403e0065c6ba576a0a4589d9115e3cf71c843c52e476b62ff4349c73838b2c2cb39f6c43d0c409ec13c315e485503ce8d1c821b0ed41ce3f39e914352973ec8ee1fefd024e106e709610bf9d500f56ec0e72c09e427cd8fd0a68bd9ef3b21176e8afd80aaef710c4022d33dc3217be4bb22144d98552ef35f23b1f10367924b4c6bea71d6c280cf2a2fff15f3c9f235cd5620bf310709aa53d6403e6d2fe6d07f13d83803a2c13a7ffdfd00150c2103009b7540e10f2562e5fd8fac9eaec25166a58b26e412348ff5a86927bfac22a20c21030205e9cefaea5a1dfc580af20c8d5aa2468bb0148f1a5e4605fc622c80e604ba0c210214baf0ceea3a66f17e7e1e839ea25fd8bed6cd82e6bb6e68250189065f44ff010c21023e9b32ea89b94d066e649b124fd50e396ee91369e8e2a6ae1b11c170d022256d0c2103408dcd416396f64783ac587ea1e1593c57d9fea880c8a6a1920e92a2594778060c2102a7834be9b32e2981d157cb5bbd3acb42cfd11ea5c3b10224d7a44e98c5910f1b0c2102ba2c70f5996f357a43198705859fae2cfea13e1172962800772b3d588a9d4abd170b41138defaf",
|
||||
"size" : 1564,
|
||||
"index" : 256,
|
||||
"primary" : 4,
|
||||
"time" : 1612366104874,
|
||||
"confirmations" : 10883,
|
||||
"consensusdata" : {
|
||||
"primary" : 4,
|
||||
"nonce" : "f636b31b0324fcfb"
|
||||
},
|
||||
"previousblockhash" : "0xfd2b68ac95461aa8ecd9ce7817bc0dea12985fc5ca52cfb5c39426e4071c1952",
|
||||
"nextconsensus" : "NgPkjjLTNcQad99iRYeXRUuowE4gxLAnDL",
|
||||
"hash" : "0x51ee44e12cdc1d3041a50d352063127fa65d86670686f14cc08f01b3cee7de17",
|
||||
"hash" : "0x63d18734a3edbe92a9480b690734b85aaf9c24361d034afbea37d749cfc62d6a",
|
||||
"witnesses" : [
|
||||
{
|
||||
"verification" : "FQwhAwCbdUDhDyVi5f2PrJ6uwlFmpYsm5BI0j/WoaSe/rCKiDCEDAgXpzvrqWh38WAryDI1aokaLsBSPGl5GBfxiLIDmBLoMIQIUuvDO6jpm8X5+HoOeol/YvtbNgua7bmglAYkGX0T/AQwhAj6bMuqJuU0GbmSbEk/VDjlu6RNp6OKmrhsRwXDQIiVtDCEDQI3NQWOW9keDrFh+oeFZPFfZ/qiAyKahkg6SollHeAYMIQKng0vpsy4pgdFXy1u9OstCz9EepcOxAiTXpE6YxZEPGwwhAroscPWZbzV6QxmHBYWfriz+oT4RcpYoAHcrPViKnUq9FwtBE43vrw==",
|
||||
|
|
|
@ -37,7 +37,7 @@ func createGenesisBlock(cfg config.ProtocolConfiguration) (*block.Block, error)
|
|||
return nil, err
|
||||
}
|
||||
|
||||
base := block.Base{
|
||||
base := block.Header{
|
||||
Version: 0,
|
||||
PrevHash: util.Uint256{},
|
||||
Timestamp: uint64(time.Date(2016, 7, 15, 15, 8, 21, 0, time.UTC).Unix()) * 1000, // Milliseconds.
|
||||
|
@ -52,12 +52,8 @@ func createGenesisBlock(cfg config.ProtocolConfiguration) (*block.Block, error)
|
|||
}
|
||||
|
||||
b := &block.Block{
|
||||
Base: base,
|
||||
Header: base,
|
||||
Transactions: []*transaction.Transaction{},
|
||||
ConsensusData: block.ConsensusData{
|
||||
PrimaryIndex: 0,
|
||||
Nonce: 2083236893,
|
||||
},
|
||||
}
|
||||
b.RebuildMerkleRoot()
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ func TestGenesisBlockMainNet(t *testing.T) {
|
|||
block, err := createGenesisBlock(cfg.ProtocolConfiguration)
|
||||
require.NoError(t, err)
|
||||
|
||||
expect := "00c6803707b564153d444bfcdf3a13325fc96dda55cc8a740bbd543a1d752fda"
|
||||
expect := "d71dfebcc59d42b2f3b3f0e0d6b3b77a4880276db1df92c08c7c1bac94bece35"
|
||||
assert.Equal(t, expect, block.Hash().StringLE())
|
||||
}
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ func buildMerkleTree(leaves []*MerkleTreeNode) *MerkleTreeNode {
|
|||
// panic.
|
||||
func CalcMerkleRoot(hashes []util.Uint256) util.Uint256 {
|
||||
if len(hashes) == 0 {
|
||||
panic("length of the hashes cannot be zero")
|
||||
return util.Uint256{}
|
||||
}
|
||||
if len(hashes) == 1 {
|
||||
return hashes[0]
|
||||
|
|
|
@ -6,11 +6,16 @@ func ToInteger(v interface{}) int {
|
|||
return v.(int)
|
||||
}
|
||||
|
||||
// ToByteArray converts it's argument to a ByteArray.
|
||||
func ToByteArray(v interface{}) []byte {
|
||||
// ToBytes converts it's argument to a Buffer VM type.
|
||||
func ToBytes(v interface{}) []byte {
|
||||
return v.([]byte)
|
||||
}
|
||||
|
||||
// ToString converts it's argument to a ByteString VM type.
|
||||
func ToString(v interface{}) string {
|
||||
return v.(string)
|
||||
}
|
||||
|
||||
// ToBool converts it's argument to a Boolean.
|
||||
func ToBool(v interface{}) bool {
|
||||
return v.(bool)
|
||||
|
|
|
@ -16,7 +16,7 @@ func TestBlockQueue(t *testing.T) {
|
|||
bq := newBlockQueue(0, chain, zaptest.NewLogger(t), nil)
|
||||
blocks := make([]*block.Block, 11)
|
||||
for i := 1; i < 11; i++ {
|
||||
blocks[i] = &block.Block{Base: block.Base{Index: uint32(i)}}
|
||||
blocks[i] = &block.Block{Header: block.Header{Index: uint32(i)}}
|
||||
}
|
||||
// not the ones expected currently
|
||||
for i := 3; i < 5; i++ {
|
||||
|
@ -33,7 +33,7 @@ func TestBlockQueue(t *testing.T) {
|
|||
assert.Equal(t, uint32(0), chain.BlockHeight())
|
||||
assert.Equal(t, 4, bq.length())
|
||||
// block with too big index is dropped
|
||||
assert.NoError(t, bq.putBlock(&block.Block{Base: block.Base{Index: bq.chain.BlockHeight() + blockCacheSize + 1}}))
|
||||
assert.NoError(t, bq.putBlock(&block.Block{Header: block.Header{Index: bq.chain.BlockHeight() + blockCacheSize + 1}}))
|
||||
assert.Equal(t, 4, bq.length())
|
||||
go bq.run()
|
||||
// run() is asynchronous, so we need some kind of timeout anyway and this is the simplest one
|
||||
|
|
|
@ -57,13 +57,11 @@ func TestEncodeDecodeHeaders(t *testing.T) {
|
|||
headers := &payload.Headers{Hdrs: make([]*block.Header, CompressionMinSize)}
|
||||
for i := range headers.Hdrs {
|
||||
h := &block.Header{
|
||||
Base: block.Base{
|
||||
Index: uint32(i + 1),
|
||||
Script: transaction.Witness{
|
||||
InvocationScript: []byte{0x0},
|
||||
VerificationScript: []byte{0x1},
|
||||
},
|
||||
},
|
||||
}
|
||||
h.Hash()
|
||||
headers.Hdrs[i] = h
|
||||
|
@ -199,7 +197,7 @@ func TestEncodeDecodeTransaction(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestEncodeDecodeMerkleBlock(t *testing.T) {
|
||||
base := &block.Base{
|
||||
base := &block.Header{
|
||||
PrevHash: random.Uint256(),
|
||||
Timestamp: rand.Uint64(),
|
||||
Script: transaction.Witness{
|
||||
|
@ -212,7 +210,7 @@ func TestEncodeDecodeMerkleBlock(t *testing.T) {
|
|||
t.Run("good", func(t *testing.T) {
|
||||
testEncodeDecode(t, CMDMerkleBlock, &payload.MerkleBlock{
|
||||
Network: netmode.UnitTestNet,
|
||||
Base: base,
|
||||
Header: base,
|
||||
TxCount: 1,
|
||||
Hashes: []util.Uint256{random.Uint256()},
|
||||
Flags: []byte{0},
|
||||
|
@ -220,7 +218,7 @@ func TestEncodeDecodeMerkleBlock(t *testing.T) {
|
|||
})
|
||||
t.Run("bad, invalid TxCount", func(t *testing.T) {
|
||||
testEncodeDecodeFail(t, CMDMerkleBlock, &payload.MerkleBlock{
|
||||
Base: base,
|
||||
Header: base,
|
||||
TxCount: 2,
|
||||
Hashes: []util.Uint256{random.Uint256()},
|
||||
Flags: []byte{0},
|
||||
|
|
|
@ -35,13 +35,11 @@ func newTestHeaders(n int) *Headers {
|
|||
|
||||
for i := range headers.Hdrs {
|
||||
headers.Hdrs[i] = &block.Header{
|
||||
Base: block.Base{
|
||||
Index: uint32(i + 1),
|
||||
Script: transaction.Witness{
|
||||
InvocationScript: []byte{0x0},
|
||||
VerificationScript: []byte{0x1},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
|
||||
// MerkleBlock represents a merkle block packet payload.
|
||||
type MerkleBlock struct {
|
||||
*block.Base
|
||||
*block.Header
|
||||
Network netmode.Magic
|
||||
TxCount int
|
||||
Hashes []util.Uint256
|
||||
|
@ -20,11 +20,11 @@ type MerkleBlock struct {
|
|||
|
||||
// DecodeBinary implements Serializable interface.
|
||||
func (m *MerkleBlock) DecodeBinary(br *io.BinReader) {
|
||||
m.Base = &block.Base{Network: m.Network}
|
||||
m.Base.DecodeBinary(br)
|
||||
m.Header = &block.Header{Network: m.Network}
|
||||
m.Header.DecodeBinary(br)
|
||||
|
||||
txCount := int(br.ReadVarUint())
|
||||
if txCount > block.MaxContentsPerBlock {
|
||||
if txCount > block.MaxTransactionsPerBlock {
|
||||
br.Err = block.ErrMaxContentsPerBlock
|
||||
return
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ func (m *MerkleBlock) DecodeBinary(br *io.BinReader) {
|
|||
|
||||
// EncodeBinary implements Serializable interface.
|
||||
func (m *MerkleBlock) EncodeBinary(bw *io.BinWriter) {
|
||||
m.Base.EncodeBinary(bw)
|
||||
m.Header.EncodeBinary(bw)
|
||||
|
||||
bw.WriteVarUint(uint64(m.TxCount))
|
||||
bw.WriteArray(m.Hashes)
|
||||
|
|
|
@ -13,8 +13,8 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
)
|
||||
|
||||
func newDumbBlock() *block.Base {
|
||||
return &block.Base{
|
||||
func newDumbBlock() *block.Header {
|
||||
return &block.Header{
|
||||
Version: 0,
|
||||
PrevHash: hash.Sha256([]byte("a")),
|
||||
MerkleRoot: hash.Sha256([]byte("b")),
|
||||
|
@ -33,7 +33,7 @@ func TestMerkleBlock_EncodeDecodeBinary(t *testing.T) {
|
|||
b := newDumbBlock()
|
||||
_ = b.Hash()
|
||||
expected := &MerkleBlock{
|
||||
Base: b,
|
||||
Header: b,
|
||||
TxCount: 0,
|
||||
Hashes: []util.Uint256{},
|
||||
Flags: []byte{},
|
||||
|
@ -45,9 +45,9 @@ func TestMerkleBlock_EncodeDecodeBinary(t *testing.T) {
|
|||
b := newDumbBlock()
|
||||
_ = b.Hash()
|
||||
expected := &MerkleBlock{
|
||||
Base: b,
|
||||
TxCount: block.MaxContentsPerBlock + 1,
|
||||
Hashes: make([]util.Uint256, block.MaxContentsPerBlock),
|
||||
Header: b,
|
||||
TxCount: block.MaxTransactionsPerBlock + 1,
|
||||
Hashes: make([]util.Uint256, block.MaxTransactionsPerBlock),
|
||||
Flags: []byte{},
|
||||
}
|
||||
data, err := testserdes.EncodeBinary(expected)
|
||||
|
@ -59,7 +59,7 @@ func TestMerkleBlock_EncodeDecodeBinary(t *testing.T) {
|
|||
b := newDumbBlock()
|
||||
_ = b.Hash()
|
||||
expected := &MerkleBlock{
|
||||
Base: b,
|
||||
Header: b,
|
||||
TxCount: 0,
|
||||
Hashes: []util.Uint256{},
|
||||
Flags: []byte{1, 2, 3, 4, 5},
|
||||
|
|
|
@ -640,7 +640,7 @@ func TestGetHeaders(t *testing.T) {
|
|||
|
||||
expected := make([]*block.Header, len(blocks))
|
||||
for i := range blocks {
|
||||
expected[i] = blocks[i].Header()
|
||||
expected[i] = &blocks[i].Header
|
||||
}
|
||||
|
||||
var actual *payload.Headers
|
||||
|
|
|
@ -46,17 +46,17 @@ type rpcClientTestCase struct {
|
|||
check func(t *testing.T, c *Client, result interface{})
|
||||
}
|
||||
|
||||
const base64B1 = "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"
|
||||
const base64B1 = "AAAAAMU1lpLU9L9XS3U0WvRgGV9aU5WoX8f6MWgNjfz89nyeomtq7Iw0SoX9caDTvpAT4ulAxcy/vWK7q9GH0raCqQfxbcftdwEAAAEAAAAAXhK+qHrrlViE9vnOeEWMzLl8MJUBxgxAVLK3uK5qryZv+jBuH0dBn7VU+sYztObj1sj65/az1v2XCrlLlL2z2LeHccRnn7jAXUE0m80q7QAxEWyhzJPA/QxAOCcAytavTTPv0uQ+rhoBRXvyxaaEdSCZq0VDJCNtI4O9iFXq+Q++GJjzA04z4QZo7KCB8KD8aruBc69i6PoqwwxAR7dzN1DAk9G1RCuSZx7X7U/qqJfT7Wa4Us9kq/40AVpJgwr0RNUGWf1Xh8K53f+tzw1UtHZMoI5YZyJtMEiQY5QTDCECEDp/fdAWVYWX95YNJ8UWpDlP2Wi55lFV60sBPkBAQG4MIQKnvFX+hoTgEZdo0QS6MHlb3MhmGehkrdJhVnI+0YXNYgwhArNiK/QBe9/jF8WK7V9MdT8ga324lgRvp9d0u8S/f43CDCED2QwH32PmkM53kS4Qq1GsyUS2aGAje2CMT4+DCece5pkUC0ETje+vAgACAAAAwNinAAAAAAASfUMAAAAAALAEAAABXhK+qHrrlViE9vnOeEWMzLl8MJUBAFsLAhjd9QUMFKqKz4WdT+QCs05nPyFWgheWpIjrDBReEr6oeuuVWIT2+c54RYzMuXwwlRTAHwwIdHJhbnNmZXIMFIOrBnmtVcBQoTrUP1k26nP16x72QWJ9W1I5AcYMQIoQAeuRy5Lgj4MYiuF9tLhAeYhKf6PrczcbKGeWmz+KNWULI+mQbeDPFWG3mGwPkSBELVqVMrUNqigZLflJhNwMQBuqOk8xrVlAx5A5Va9FlMhu3io+wIrubPoWNr0sklBKh48H9w3WHPfTFBSAW8M9ePou/TVXM40X+U07fy+s+8MMQIlw1AKX/fk1rn1GqjZOqNmhVjQPm6Tk7Cb1fzeBa4baIEy5DmaaM8ayh0tm8N3Vc8JNSwnK91vIXPG/A9RKTKuUEwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrwADAAAAwNinAAAAAACyjEMAAAAAALAEAAABXhK+qHrrlViE9vnOeEWMzLl8MJUBAF8LAwDodkgXAAAADBSqis+FnU/kArNOZz8hVoIXlqSI6wwUXhK+qHrrlViE9vnOeEWMzLl8MJUUwB8MCHRyYW5zZmVyDBQos62rcmn5whgds8t0Hr9VGTDicEFifVtSOQHGDEA7aJyGTIq0pV20LzVWOCreh6XIxLUCWHVgUFsCTxPOPdqtZBHKnejng3d2BRm/lecTyPLeq7KpRCD9awRvadFWDEBjVZRvSGtGcOEjtUxl4AH5XelYlIUG5k+x3QyYKZtWQc96lUX1hohrNkCmWeWNwC2l8eJGpUxicM+WZGODCVp8DEDbQxvmqRTQ+flc6JetmaqHyw8rfoeQNtmEFpw2cNhyAo5L5Ilp2wbVtJNOJPfw72J7E6FhTK8slIKRqXzpdnyKlBMMIQIQOn990BZVhZf3lg0nxRakOU/ZaLnmUVXrSwE+QEBAbgwhAqe8Vf6GhOARl2jRBLoweVvcyGYZ6GSt0mFWcj7Rhc1iDCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcIMIQPZDAffY+aQzneRLhCrUazJRLZoYCN7YIxPj4MJ5x7mmRQLQRON768="
|
||||
|
||||
const base64TxMoveNeo = "AAIAAACAlpgAAAAAAJ58RAAAAAAAsAQAAAFeEr6oeuuVWIT2+c54RYzMuXwwlQEAWQIY3fUFDBSqis+FnU/kArNOZz8hVoIXlqSI6wwUXhK+qHrrlViE9vnOeEWMzLl8MJUTwAwIdHJhbnNmZXIMFCUFnstIeNOodfkcUc7e0zDUV1/eQWJ9W1I4Af0IAQxACHElLALUapeLfiBHqPqePmCO2wOjxvtccVJDyG9rzZWjJeD7po0FRU/m4NpXcQmGus3HKHOJ9Bn68ovNhIRqRgxAkeH0A6+J46PeJhevxgPjh9GOZO9+chjBGR7PeufOgUaen9AEMX5iD7y3EuGHq6PadM4FZfQQ4N08VOaYkcpUeQxAHIzk+yYxMDUZyoAw5F34et2HNzKKzG3W9mrE4g7tGnscuTOV3IpANY8qSU+MJIcY6dK64BWUUs3mIcFdCpc/sgxAiKKSsS3eKfoSx8RatO1n313fvrDdFiEVs7zCZ3Aqyakj/M8+ua/ExhRc72THRnpVijuyoQToSCusK8rljZWgyJQTDCECEDp/fdAWVYWX95YNJ8UWpDlP2Wi55lFV60sBPkBAQG4MIQKnvFX+hoTgEZdo0QS6MHlb3MhmGehkrdJhVnI+0YXNYgwhArNiK/QBe9/jF8WK7V9MdT8ga324lgRvp9d0u8S/f43CDCED2QwH32PmkM53kS4Qq1GsyUS2aGAje2CMT4+DCece5pkUC0ETje+v"
|
||||
const base64TxMoveNeo = "AAIAAADA2KcAAAAAABJ9QwAAAAAAsAQAAAFeEr6oeuuVWIT2+c54RYzMuXwwlQEAWwsCGN31BQwUqorPhZ1P5AKzTmc/IVaCF5akiOsMFF4Svqh665VYhPb5znhFjMy5fDCVFMAfDAh0cmFuc2ZlcgwUg6sGea1VwFChOtQ/WTbqc/XrHvZBYn1bUjkBxgxAihAB65HLkuCPgxiK4X20uEB5iEp/o+tzNxsoZ5abP4o1ZQsj6ZBt4M8VYbeYbA+RIEQtWpUytQ2qKBkt+UmE3AxAG6o6TzGtWUDHkDlVr0WUyG7eKj7Aiu5s+hY2vSySUEqHjwf3DdYc99MUFIBbwz14+i79NVczjRf5TTt/L6z7wwxAiXDUApf9+TWufUaqNk6o2aFWNA+bpOTsJvV/N4FrhtogTLkOZpozxrKHS2bw3dVzwk1LCcr3W8hc8b8D1EpMq5QTDCECEDp/fdAWVYWX95YNJ8UWpDlP2Wi55lFV60sBPkBAQG4MIQKnvFX+hoTgEZdo0QS6MHlb3MhmGehkrdJhVnI+0YXNYgwhArNiK/QBe9/jF8WK7V9MdT8ga324lgRvp9d0u8S/f43CDCED2QwH32PmkM53kS4Qq1GsyUS2aGAje2CMT4+DCece5pkUC0ETje+v"
|
||||
|
||||
const b1Verbose = `{"id":5,"jsonrpc":"2.0","result":{"size":1641,"nextblockhash":"0x003abea54aa3c5edba7e33fb7ca96452cb65ff8cd36ce1cdfd412a6c4d3ea38a","confirmations":6,"hash":"0xd9518e322440714b0564d6f84a9a39b527b5480e4e7f7932895777a4c8fa0a9e","version":0,"previousblockhash":"0xa496577895eb8c227bb866dc44f99f21c0cf06417ca8f2a877cc5d761a50dac0","merkleroot":"0x2b0f84636d814f3a952de145c8f4028f5664132f2719f5902e1884c9fba59806","time":1596101407001,"index":1,"nextconsensus":"NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY","witnesses":[{"invocation":"DEANAGtuw7+VLVNvmpESGL4+xqlKgBSIWmMBEtABi86ixft2Q7AcaOC89M+yKVIuTel9doVJcCvfx93CcQ63DZqCDEBtwUEkjuzP9h8ZTL0GEKfGr01pazmh8s2TswJge5sAGryYE/+kjw5NCLFmowhPU73qUYQ9jq1zMNMXF+Deqxp/DEDkytkkwJec5n4x2+l5zsZHT6QTXJsByZOWXaGPVJKK8CeDccZba7Mf4MdSkWqSt61xUtlgM2Iqhe/Iuokf/ZEXDEAOH72S12CuAxVu0XNGyj3cgMtad+Bghxvr16T9+ELaWkpR4ko26FdStYC2XiCkzanXTtAD1Id5rREsxfFeKb83","verification":"EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrw=="}],"consensusdata":{"primary":0,"nonce":"0000000000000457"},"tx":[{"hash":"0x32f9bd3a2707475407c41bf5daacf9560e25ed74f6d85b3afb2ef72edb2325ba","size":555,"version":0,"nonce":2,"sender":"NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY","sysfee":"10000000","netfee":"4488350","validuntilblock":1200,"attributes":[],"signers":[{"account":"0x95307cb9cc8c4578cef9f6845895eb7aa8be125e","scopes":"CalledByEntry"}],"script":"Ahjd9QUMFKqKz4WdT+QCs05nPyFWgheWpIjrDBReEr6oeuuVWIT2+c54RYzMuXwwlRPADAh0cmFuc2ZlcgwUJQWey0h406h1+RxRzt7TMNRXX95BYn1bUjg=","witnesses":[{"invocation":"DEAIcSUsAtRql4t+IEeo+p4+YI7bA6PG+1xxUkPIb2vNlaMl4PumjQVFT+bg2ldxCYa6zccoc4n0Gfryi82EhGpGDECR4fQDr4njo94mF6/GA+OH0Y5k735yGMEZHs96586BRp6f0AQxfmIPvLcS4Yero9p0zgVl9BDg3TxU5piRylR5DEAcjOT7JjEwNRnKgDDkXfh63Yc3MorMbdb2asTiDu0aexy5M5XcikA1jypJT4wkhxjp0rrgFZRSzeYhwV0Klz+yDECIopKxLd4p+hLHxFq07WffXd++sN0WIRWzvMJncCrJqSP8zz65r8TGFFzvZMdGelWKO7KhBOhIK6wryuWNlaDI","verification":"EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrw=="}]},{"hash":"0xd35d6386ec2f29b90839536f6af9466098d1665e951cdd0a20db6b4629b08369","size":559,"version":0,"nonce":3,"sender":"NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY","sysfee":"10000000","netfee":"4492350","validuntilblock":1200,"attributes":[],"signers":[{"account":"0x95307cb9cc8c4578cef9f6845895eb7aa8be125e","scopes":"CalledByEntry"}],"script":"AwDodkgXAAAADBSqis+FnU/kArNOZz8hVoIXlqSI6wwUXhK+qHrrlViE9vnOeEWMzLl8MJUTwAwIdHJhbnNmZXIMFLyvQdaEx9StbuDZnalwe50fDI5mQWJ9W1I4","witnesses":[{"invocation":"DECKUPl9d502XPI564EC2BroqpN274uV3n1z6kCBCmbS715lzmPbh24LESMsAP2TFohhdhm16aDfNsPi5tkB/FE4DEDzJFts9VYc1lIivGAZZSxACzAV/96Kn2WAaS3bDIlAJHCShsfz+Rn3NuvMyutujYM4vyEipAX9gkjcvFWGKRObDECkI883onhG9aYTxwQWDxsmofuiooRJOic/cJ1H8nqUEvMqATYKgdHaBOJBVYsKq9M9oUv/fj6JFbMDrcasvpiaDECEqkq2b50aEc1NGM9DBAsYLEeZHrM1BwX3a2tBOeeD/KLtmTga1IZogsZgpis2BOToZO6LuN9FJYcn+/iGcC5u","verification":"EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrw=="}]}]}}`
|
||||
const b1Verbose = `{"id":5,"jsonrpc":"2.0","result":{"size":1433,"nextblockhash":"0x85ab779bc19247aa504c36879ce75cb7f662b4e8067fbc83e5d24ef0afd9a84f","confirmations":6,"hash":"0xea6385e943832b65ee225aaeb31933a97f3362505ab84cfe5dbd91cd1672b9b7","version":0,"previousblockhash":"0x9e7cf6fcfc8d0d6831fac75fa895535a5f1960f45a34754b57bff4d4929635c5","merkleroot":"0x07a982b6d287d1abbb62bdbfccc540e9e21390bed3a071fd854a348cec6a6ba2","time":1614602006001,"index":1,"nextconsensus":"NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY","primary":0,"witnesses":[{"invocation":"DEBUsre4rmqvJm/6MG4fR0GftVT6xjO05uPWyPrn9rPW/ZcKuUuUvbPYt4dxxGefuMBdQTSbzSrtADERbKHMk8D9DEA4JwDK1q9NM+/S5D6uGgFFe/LFpoR1IJmrRUMkI20jg72IVer5D74YmPMDTjPhBmjsoIHwoPxqu4Fzr2Lo+irDDEBHt3M3UMCT0bVEK5JnHtftT+qol9PtZrhSz2Sr/jQBWkmDCvRE1QZZ/VeHwrnd/63PDVS0dkygjlhnIm0wSJBj","verification":"EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrw=="}],"tx":[{"hash":"0x7c10b90077bddfe9095b2db96bb4ac33994ed1ca99c805410f55c771eee0b77b","size":489,"version":0,"nonce":2,"sender":"NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY","sysfee":"11000000","netfee":"4422930","validuntilblock":1200,"attributes":[],"signers":[{"account":"0x95307cb9cc8c4578cef9f6845895eb7aa8be125e","scopes":"CalledByEntry"}],"script":"CwIY3fUFDBSqis+FnU/kArNOZz8hVoIXlqSI6wwUXhK+qHrrlViE9vnOeEWMzLl8MJUUwB8MCHRyYW5zZmVyDBSDqwZ5rVXAUKE61D9ZNupz9ese9kFifVtSOQ==","witnesses":[{"invocation":"DECKEAHrkcuS4I+DGIrhfbS4QHmISn+j63M3Gyhnlps/ijVlCyPpkG3gzxVht5hsD5EgRC1alTK1DaooGS35SYTcDEAbqjpPMa1ZQMeQOVWvRZTIbt4qPsCK7mz6Fja9LJJQSoePB/cN1hz30xQUgFvDPXj6Lv01VzONF/lNO38vrPvDDECJcNQCl/35Na59Rqo2TqjZoVY0D5uk5Owm9X83gWuG2iBMuQ5mmjPGsodLZvDd1XPCTUsJyvdbyFzxvwPUSkyr","verification":"EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrw=="}]},{"hash":"0x41846075f4c5aec54d70b476befb97b35696700454b1168e1ae8888d8fb204a3","size":493,"version":0,"nonce":3,"sender":"NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY","sysfee":"11000000","netfee":"4426930","validuntilblock":1200,"attributes":[],"signers":[{"account":"0x95307cb9cc8c4578cef9f6845895eb7aa8be125e","scopes":"CalledByEntry"}],"script":"CwMA6HZIFwAAAAwUqorPhZ1P5AKzTmc/IVaCF5akiOsMFF4Svqh665VYhPb5znhFjMy5fDCVFMAfDAh0cmFuc2ZlcgwUKLOtq3Jp+cIYHbPLdB6/VRkw4nBBYn1bUjk=","witnesses":[{"invocation":"DEA7aJyGTIq0pV20LzVWOCreh6XIxLUCWHVgUFsCTxPOPdqtZBHKnejng3d2BRm/lecTyPLeq7KpRCD9awRvadFWDEBjVZRvSGtGcOEjtUxl4AH5XelYlIUG5k+x3QyYKZtWQc96lUX1hohrNkCmWeWNwC2l8eJGpUxicM+WZGODCVp8DEDbQxvmqRTQ+flc6JetmaqHyw8rfoeQNtmEFpw2cNhyAo5L5Ilp2wbVtJNOJPfw72J7E6FhTK8slIKRqXzpdnyK","verification":"EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrw=="}]}]}}`
|
||||
|
||||
const base64Header1 = "AAAAAMDaUBp2Xcx3qPKofEEGz8Ahn/lE3Ga4eyKM65V4V5akBpil+8mEGC6Q9RknLxNkVo8C9MhF4S2VOk+BbWOEDysZsQ6fcwEAAAEAAABeEr6oeuuVWIT2+c54RYzMuXwwlQH9CAEMQA0Aa27Dv5UtU2+akRIYvj7GqUqAFIhaYwES0AGLzqLF+3ZDsBxo4Lz0z7IpUi5N6X12hUlwK9/H3cJxDrcNmoIMQG3BQSSO7M/2HxlMvQYQp8avTWlrOaHyzZOzAmB7mwAavJgT/6SPDk0IsWajCE9TvepRhD2OrXMw0xcX4N6rGn8MQOTK2STAl5zmfjHb6XnOxkdPpBNcmwHJk5ZdoY9UkorwJ4Nxxltrsx/gx1KRapK3rXFS2WAzYiqF78i6iR/9kRcMQA4fvZLXYK4DFW7Rc0bKPdyAy1p34GCHG+vXpP34QtpaSlHiSjboV1K1gLZeIKTNqddO0APUh3mtESzF8V4pvzeUEwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrwA="
|
||||
const base64Header1 = "AAAAAMU1lpLU9L9XS3U0WvRgGV9aU5WoX8f6MWgNjfz89nyeomtq7Iw0SoX9caDTvpAT4ulAxcy/vWK7q9GH0raCqQfxbcftdwEAAAEAAAAAXhK+qHrrlViE9vnOeEWMzLl8MJUBxgxAVLK3uK5qryZv+jBuH0dBn7VU+sYztObj1sj65/az1v2XCrlLlL2z2LeHccRnn7jAXUE0m80q7QAxEWyhzJPA/QxAOCcAytavTTPv0uQ+rhoBRXvyxaaEdSCZq0VDJCNtI4O9iFXq+Q++GJjzA04z4QZo7KCB8KD8aruBc69i6PoqwwxAR7dzN1DAk9G1RCuSZx7X7U/qqJfT7Wa4Us9kq/40AVpJgwr0RNUGWf1Xh8K53f+tzw1UtHZMoI5YZyJtMEiQY5QTDCECEDp/fdAWVYWX95YNJ8UWpDlP2Wi55lFV60sBPkBAQG4MIQKnvFX+hoTgEZdo0QS6MHlb3MhmGehkrdJhVnI+0YXNYgwhArNiK/QBe9/jF8WK7V9MdT8ga324lgRvp9d0u8S/f43CDCED2QwH32PmkM53kS4Qq1GsyUS2aGAje2CMT4+DCece5pkUC0ETje+vAA=="
|
||||
|
||||
const header1Verbose = `{"id":5,"jsonrpc":"2.0","result":{"hash":"0xd9518e322440714b0564d6f84a9a39b527b5480e4e7f7932895777a4c8fa0a9e","size":518,"version":0,"previousblockhash":"0xa496577895eb8c227bb866dc44f99f21c0cf06417ca8f2a877cc5d761a50dac0","merkleroot":"0x2b0f84636d814f3a952de145c8f4028f5664132f2719f5902e1884c9fba59806","time":1596101407001,"index":1,"nextconsensus":"NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY","witnesses":[{"invocation":"DEANAGtuw7+VLVNvmpESGL4+xqlKgBSIWmMBEtABi86ixft2Q7AcaOC89M+yKVIuTel9doVJcCvfx93CcQ63DZqCDEBtwUEkjuzP9h8ZTL0GEKfGr01pazmh8s2TswJge5sAGryYE/+kjw5NCLFmowhPU73qUYQ9jq1zMNMXF+Deqxp/DEDkytkkwJec5n4x2+l5zsZHT6QTXJsByZOWXaGPVJKK8CeDccZba7Mf4MdSkWqSt61xUtlgM2Iqhe/Iuokf/ZEXDEAOH72S12CuAxVu0XNGyj3cgMtad+Bghxvr16T9+ELaWkpR4ko26FdStYC2XiCkzanXTtAD1Id5rREsxfFeKb83","verification":"EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrw=="}],"confirmations":6,"nextblockhash":"0x003abea54aa3c5edba7e33fb7ca96452cb65ff8cd36ce1cdfd412a6c4d3ea38a"}}`
|
||||
const header1Verbose = `{"id":5,"jsonrpc":"2.0","result":{"hash":"0xea6385e943832b65ee225aaeb31933a97f3362505ab84cfe5dbd91cd1672b9b7","size":451,"version":0,"previousblockhash":"0x9e7cf6fcfc8d0d6831fac75fa895535a5f1960f45a34754b57bff4d4929635c5","merkleroot":"0x07a982b6d287d1abbb62bdbfccc540e9e21390bed3a071fd854a348cec6a6ba2","time":1614602006001,"index":1,"nextconsensus":"NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY","witnesses":[{"invocation":"DEBUsre4rmqvJm/6MG4fR0GftVT6xjO05uPWyPrn9rPW/ZcKuUuUvbPYt4dxxGefuMBdQTSbzSrtADERbKHMk8D9DEA4JwDK1q9NM+/S5D6uGgFFe/LFpoR1IJmrRUMkI20jg72IVer5D74YmPMDTjPhBmjsoIHwoPxqu4Fzr2Lo+irDDEBHt3M3UMCT0bVEK5JnHtftT+qol9PtZrhSz2Sr/jQBWkmDCvRE1QZZ/VeHwrnd/63PDVS0dkygjlhnIm0wSJBj","verification":"EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrw=="}],"confirmations":6,"nextblockhash":"0x85ab779bc19247aa504c36879ce75cb7f662b4e8067fbc83e5d24ef0afd9a84f"}}`
|
||||
|
||||
const txMoveNeoVerbose = `{"id":5,"jsonrpc":"2.0","result":{"blockhash":"0xd9518e322440714b0564d6f84a9a39b527b5480e4e7f7932895777a4c8fa0a9e","confirmations":6,"blocktime":1596101407001,"vmstate":"","hash":"0x32f9bd3a2707475407c41bf5daacf9560e25ed74f6d85b3afb2ef72edb2325ba","size":555,"version":0,"nonce":2,"sender":"NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY","sysfee":"10000000","netfee":"4488350","validuntilblock":1200,"attributes":[],"signers":[{"account":"0x95307cb9cc8c4578cef9f6845895eb7aa8be125e","scopes":"CalledByEntry"}],"script":"Ahjd9QUMFKqKz4WdT+QCs05nPyFWgheWpIjrDBReEr6oeuuVWIT2+c54RYzMuXwwlRPADAh0cmFuc2ZlcgwUJQWey0h406h1+RxRzt7TMNRXX95BYn1bUjg=","witnesses":[{"invocation":"DEAIcSUsAtRql4t+IEeo+p4+YI7bA6PG+1xxUkPIb2vNlaMl4PumjQVFT+bg2ldxCYa6zccoc4n0Gfryi82EhGpGDECR4fQDr4njo94mF6/GA+OH0Y5k735yGMEZHs96586BRp6f0AQxfmIPvLcS4Yero9p0zgVl9BDg3TxU5piRylR5DEAcjOT7JjEwNRnKgDDkXfh63Yc3MorMbdb2asTiDu0aexy5M5XcikA1jypJT4wkhxjp0rrgFZRSzeYhwV0Klz+yDECIopKxLd4p+hLHxFq07WffXd++sN0WIRWzvMJncCrJqSP8zz65r8TGFFzvZMdGelWKO7KhBOhIK6wryuWNlaDI","verification":"EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrw=="}]}}`
|
||||
const txMoveNeoVerbose = `{"id":5,"jsonrpc":"2.0","result":{"blockhash":"0xea6385e943832b65ee225aaeb31933a97f3362505ab84cfe5dbd91cd1672b9b7","confirmations":6,"blocktime":1614602006001,"vmstate":"HALT","hash":"0x7c10b90077bddfe9095b2db96bb4ac33994ed1ca99c805410f55c771eee0b77b","size":489,"version":0,"nonce":2,"sender":"NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY","sysfee":"11000000","netfee":"4422930","validuntilblock":1200,"attributes":[],"signers":[{"account":"0x95307cb9cc8c4578cef9f6845895eb7aa8be125e","scopes":"CalledByEntry"}],"script":"CwIY3fUFDBSqis+FnU/kArNOZz8hVoIXlqSI6wwUXhK+qHrrlViE9vnOeEWMzLl8MJUUwB8MCHRyYW5zZmVyDBSDqwZ5rVXAUKE61D9ZNupz9ese9kFifVtSOQ==","witnesses":[{"invocation":"DECKEAHrkcuS4I+DGIrhfbS4QHmISn+j63M3Gyhnlps/ijVlCyPpkG3gzxVht5hsD5EgRC1alTK1DaooGS35SYTcDEAbqjpPMa1ZQMeQOVWvRZTIbt4qPsCK7mz6Fja9LJJQSoePB/cN1hz30xQUgFvDPXj6Lv01VzONF/lNO38vrPvDDECJcNQCl/35Na59Rqo2TqjZoVY0D5uk5Owm9X83gWuG2iBMuQ5mmjPGsodLZvDd1XPCTUsJyvdbyFzxvwPUSkyr","verification":"EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrw=="}]}}`
|
||||
|
||||
// getResultBlock1 returns data for block number 1 which is used by several tests.
|
||||
func getResultBlock1() *result.Block {
|
||||
|
@ -69,14 +69,14 @@ func getResultBlock1() *result.Block {
|
|||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
b2Hash, err := util.Uint256DecodeStringLE("003abea54aa3c5edba7e33fb7ca96452cb65ff8cd36ce1cdfd412a6c4d3ea38a")
|
||||
b2Hash, err := util.Uint256DecodeStringLE("85ab779bc19247aa504c36879ce75cb7f662b4e8067fbc83e5d24ef0afd9a84f")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return &result.Block{
|
||||
Block: *b,
|
||||
BlockMetadata: result.BlockMetadata{
|
||||
Size: 1641,
|
||||
Size: 1433,
|
||||
NextBlockHash: &b2Hash,
|
||||
Confirmations: 6,
|
||||
},
|
||||
|
@ -99,6 +99,7 @@ func getTxMoveNeo() *result.TransactionOutputRaw {
|
|||
Timestamp: b1.Timestamp,
|
||||
Blockhash: b1.Block.Hash(),
|
||||
Confirmations: int(b1.Confirmations),
|
||||
VMState: "HALT",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -170,8 +171,6 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
|
|||
serverResponse: b1Verbose,
|
||||
result: func(c *Client) interface{} {
|
||||
res := getResultBlock1()
|
||||
// update hidden hash value.
|
||||
_ = res.Block.ConsensusData.Hash()
|
||||
return res
|
||||
},
|
||||
},
|
||||
|
@ -202,8 +201,6 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
|
|||
serverResponse: b1Verbose,
|
||||
result: func(c *Client) interface{} {
|
||||
res := getResultBlock1()
|
||||
// update hidden hash value.
|
||||
_ = res.Block.ConsensusData.Hash()
|
||||
return res
|
||||
},
|
||||
},
|
||||
|
@ -249,7 +246,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
|
|||
serverResponse: `{"id":1,"jsonrpc":"2.0","result":"` + base64Header1 + `"}`,
|
||||
result: func(c *Client) interface{} {
|
||||
b := getResultBlock1()
|
||||
return b.Header()
|
||||
return &b.Header
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -266,7 +263,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
|
|||
b := getResultBlock1()
|
||||
return &result.Header{
|
||||
Hash: b.Hash(),
|
||||
Size: 518,
|
||||
Size: 451,
|
||||
Version: b.Version,
|
||||
NextBlockHash: b.NextBlockHash,
|
||||
PrevBlockHash: b.PrevHash,
|
||||
|
@ -582,7 +579,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
|
|||
{
|
||||
name: "verbose_positive",
|
||||
invoke: func(c *Client) (interface{}, error) {
|
||||
hash, err := util.Uint256DecodeStringLE("8185b0db7ed77190b93ac8bd44896822cd8f3cfcf702b3f50131e0efd200ef96")
|
||||
hash, err := util.Uint256DecodeStringLE("7c10b90077bddfe9095b2db96bb4ac33994ed1ca99c805410f55c771eee0b77b")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -887,7 +884,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
|
|||
name: "positive",
|
||||
invoke: func(c *Client) (interface{}, error) {
|
||||
return c.SubmitBlock(block.Block{
|
||||
Base: block.Base{},
|
||||
Header: block.Header{},
|
||||
Transactions: nil,
|
||||
Trimmed: false,
|
||||
})
|
||||
|
@ -1014,7 +1011,7 @@ var rpcClientErrorCases = map[string][]rpcClientErrorCase{
|
|||
name: "submitblock_bad_server_answer",
|
||||
invoke: func(c *Client) (interface{}, error) {
|
||||
return c.SubmitBlock(block.Block{
|
||||
Base: block.Base{},
|
||||
Header: block.Header{},
|
||||
Transactions: nil,
|
||||
Trimmed: false,
|
||||
})
|
||||
|
@ -1375,7 +1372,7 @@ var rpcClientErrorCases = map[string][]rpcClientErrorCase{
|
|||
name: "submitblock_unmarshalling_error",
|
||||
invoke: func(c *Client) (interface{}, error) {
|
||||
return c.SubmitBlock(block.Block{
|
||||
Base: block.Base{},
|
||||
Header: block.Header{},
|
||||
Transactions: nil,
|
||||
Trimmed: false,
|
||||
})
|
||||
|
|
|
@ -118,7 +118,7 @@ func TestWSClientEvents(t *testing.T) {
|
|||
`{"jsonrpc":"2.0","method":"transaction_executed","params":[{"container":"0xe1cd5e57e721d2a2e05fb1f08721b12057b25ab1dd7fd0f33ee1639932fdfad7","trigger":"Application","vmstate":"HALT","gasconsumed":"22910000","stack":[],"notifications":[{"contract":"0x1b4357bff5a01bdf2a6581247cf9ed1e24629176","eventname":"contract call","state":{"type":"Array","value":[{"type":"ByteString","value":"dHJhbnNmZXI="},{"type":"Array","value":[{"type":"ByteString","value":"dpFiJB7t+XwkgWUq3xug9b9XQxs="},{"type":"ByteString","value":"MW6FEDkBnTnfwsN9bD/uGf1YCYc="},{"type":"Integer","value":"1000"}]}]}},{"contract":"0x1b4357bff5a01bdf2a6581247cf9ed1e24629176","eventname":"transfer","state":{"type":"Array","value":[{"type":"ByteString","value":"dpFiJB7t+XwkgWUq3xug9b9XQxs="},{"type":"ByteString","value":"MW6FEDkBnTnfwsN9bD/uGf1YCYc="},{"type":"Integer","value":"1000"}]}}]}]}`,
|
||||
`{"jsonrpc":"2.0","method":"notification_from_execution","params":[{"contract":"0x1b4357bff5a01bdf2a6581247cf9ed1e24629176","eventname":"contract call","state":{"type":"Array","value":[{"type":"ByteString","value":"dHJhbnNmZXI="},{"type":"Array","value":[{"type":"ByteString","value":"dpFiJB7t+XwkgWUq3xug9b9XQxs="},{"type":"ByteString","value":"MW6FEDkBnTnfwsN9bD/uGf1YCYc="},{"type":"Integer","value":"1000"}]}]}}]}`,
|
||||
`{"jsonrpc":"2.0","method":"transaction_executed","params":[{"container":"0xf97a72b7722c109f909a8bc16c22368c5023d85828b09b127b237aace33cf099","trigger":"Application","vmstate":"HALT","gasconsumed":"6042610","stack":[],"notifications":[{"contract":"0xe65ff7b3a02d207b584a5c27057d4e9862ef01da","eventname":"contract call","state":{"type":"Array","value":[{"type":"ByteString","value":"dHJhbnNmZXI="},{"type":"Array","value":[{"type":"ByteString","value":"MW6FEDkBnTnfwsN9bD/uGf1YCYc="},{"type":"ByteString","value":"IHKCdK+vw29DoHHTKM+j5inZy7A="},{"type":"Integer","value":"123"}]}]}},{"contract":"0xe65ff7b3a02d207b584a5c27057d4e9862ef01da","eventname":"transfer","state":{"type":"Array","value":[{"type":"ByteString","value":"MW6FEDkBnTnfwsN9bD/uGf1YCYc="},{"type":"ByteString","value":"IHKCdK+vw29DoHHTKM+j5inZy7A="},{"type":"Integer","value":"123"}]}}]}]}`,
|
||||
`{"jsonrpc":"2.0","method":"block_added","params":[{"size":1641,"nextblockhash":"0x003abea54aa3c5edba7e33fb7ca96452cb65ff8cd36ce1cdfd412a6c4d3ea38a","confirmations":6,"hash":"0xd9518e322440714b0564d6f84a9a39b527b5480e4e7f7932895777a4c8fa0a9e","version":0,"previousblockhash":"0xa496577895eb8c227bb866dc44f99f21c0cf06417ca8f2a877cc5d761a50dac0","merkleroot":"0x2b0f84636d814f3a952de145c8f4028f5664132f2719f5902e1884c9fba59806","time":1596101407001,"index":1,"nextconsensus":"NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY","witnesses":[{"invocation":"DEANAGtuw7+VLVNvmpESGL4+xqlKgBSIWmMBEtABi86ixft2Q7AcaOC89M+yKVIuTel9doVJcCvfx93CcQ63DZqCDEBtwUEkjuzP9h8ZTL0GEKfGr01pazmh8s2TswJge5sAGryYE/+kjw5NCLFmowhPU73qUYQ9jq1zMNMXF+Deqxp/DEDkytkkwJec5n4x2+l5zsZHT6QTXJsByZOWXaGPVJKK8CeDccZba7Mf4MdSkWqSt61xUtlgM2Iqhe/Iuokf/ZEXDEAOH72S12CuAxVu0XNGyj3cgMtad+Bghxvr16T9+ELaWkpR4ko26FdStYC2XiCkzanXTtAD1Id5rREsxfFeKb83","verification":"EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrw=="}],"consensusdata":{"primary":0,"nonce":"0000000000000457"},"tx":[{"hash":"0x32f9bd3a2707475407c41bf5daacf9560e25ed74f6d85b3afb2ef72edb2325ba","size":555,"version":0,"nonce":2,"sender":"NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY","sysfee":"10000000","netfee":"4488350","validuntilblock":1200,"attributes":[],"signers":[{"account":"0x95307cb9cc8c4578cef9f6845895eb7aa8be125e","scopes":"CalledByEntry"}],"script":"Ahjd9QUMFKqKz4WdT+QCs05nPyFWgheWpIjrDBReEr6oeuuVWIT2+c54RYzMuXwwlRPADAh0cmFuc2ZlcgwUJQWey0h406h1+RxRzt7TMNRXX95BYn1bUjg=","witnesses":[{"invocation":"DEAIcSUsAtRql4t+IEeo+p4+YI7bA6PG+1xxUkPIb2vNlaMl4PumjQVFT+bg2ldxCYa6zccoc4n0Gfryi82EhGpGDECR4fQDr4njo94mF6/GA+OH0Y5k735yGMEZHs96586BRp6f0AQxfmIPvLcS4Yero9p0zgVl9BDg3TxU5piRylR5DEAcjOT7JjEwNRnKgDDkXfh63Yc3MorMbdb2asTiDu0aexy5M5XcikA1jypJT4wkhxjp0rrgFZRSzeYhwV0Klz+yDECIopKxLd4p+hLHxFq07WffXd++sN0WIRWzvMJncCrJqSP8zz65r8TGFFzvZMdGelWKO7KhBOhIK6wryuWNlaDI","verification":"EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrw=="}]},{"hash":"0xd35d6386ec2f29b90839536f6af9466098d1665e951cdd0a20db6b4629b08369","size":559,"version":0,"nonce":3,"sender":"NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY","sysfee":"10000000","netfee":"4492350","validuntilblock":1200,"attributes":[],"signers":[{"account":"0x95307cb9cc8c4578cef9f6845895eb7aa8be125e","scopes":"CalledByEntry"}],"script":"AwDodkgXAAAADBSqis+FnU/kArNOZz8hVoIXlqSI6wwUXhK+qHrrlViE9vnOeEWMzLl8MJUTwAwIdHJhbnNmZXIMFLyvQdaEx9StbuDZnalwe50fDI5mQWJ9W1I4","witnesses":[{"invocation":"DECKUPl9d502XPI564EC2BroqpN274uV3n1z6kCBCmbS715lzmPbh24LESMsAP2TFohhdhm16aDfNsPi5tkB/FE4DEDzJFts9VYc1lIivGAZZSxACzAV/96Kn2WAaS3bDIlAJHCShsfz+Rn3NuvMyutujYM4vyEipAX9gkjcvFWGKRObDECkI883onhG9aYTxwQWDxsmofuiooRJOic/cJ1H8nqUEvMqATYKgdHaBOJBVYsKq9M9oUv/fj6JFbMDrcasvpiaDECEqkq2b50aEc1NGM9DBAsYLEeZHrM1BwX3a2tBOeeD/KLtmTga1IZogsZgpis2BOToZO6LuN9FJYcn+/iGcC5u","verification":"EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrw=="}]}]}]}`,
|
||||
`{"jsonrpc":"2.0","method":"block_added","params":[{"size":1433,"nextblockhash":"0x85ab779bc19247aa504c36879ce75cb7f662b4e8067fbc83e5d24ef0afd9a84f","confirmations":6,"hash":"0xea6385e943832b65ee225aaeb31933a97f3362505ab84cfe5dbd91cd1672b9b7","version":0,"previousblockhash":"0x9e7cf6fcfc8d0d6831fac75fa895535a5f1960f45a34754b57bff4d4929635c5","merkleroot":"0x07a982b6d287d1abbb62bdbfccc540e9e21390bed3a071fd854a348cec6a6ba2","time":1614602006001,"index":1,"nextconsensus":"NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY","primary":0,"witnesses":[{"invocation":"DEBUsre4rmqvJm/6MG4fR0GftVT6xjO05uPWyPrn9rPW/ZcKuUuUvbPYt4dxxGefuMBdQTSbzSrtADERbKHMk8D9DEA4JwDK1q9NM+/S5D6uGgFFe/LFpoR1IJmrRUMkI20jg72IVer5D74YmPMDTjPhBmjsoIHwoPxqu4Fzr2Lo+irDDEBHt3M3UMCT0bVEK5JnHtftT+qol9PtZrhSz2Sr/jQBWkmDCvRE1QZZ/VeHwrnd/63PDVS0dkygjlhnIm0wSJBj","verification":"EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrw=="}],"tx":[{"hash":"0x7c10b90077bddfe9095b2db96bb4ac33994ed1ca99c805410f55c771eee0b77b","size":489,"version":0,"nonce":2,"sender":"NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY","sysfee":"11000000","netfee":"4422930","validuntilblock":1200,"attributes":[],"signers":[{"account":"0x95307cb9cc8c4578cef9f6845895eb7aa8be125e","scopes":"CalledByEntry"}],"script":"CwIY3fUFDBSqis+FnU/kArNOZz8hVoIXlqSI6wwUXhK+qHrrlViE9vnOeEWMzLl8MJUUwB8MCHRyYW5zZmVyDBSDqwZ5rVXAUKE61D9ZNupz9ese9kFifVtSOQ==","witnesses":[{"invocation":"DECKEAHrkcuS4I+DGIrhfbS4QHmISn+j63M3Gyhnlps/ijVlCyPpkG3gzxVht5hsD5EgRC1alTK1DaooGS35SYTcDEAbqjpPMa1ZQMeQOVWvRZTIbt4qPsCK7mz6Fja9LJJQSoePB/cN1hz30xQUgFvDPXj6Lv01VzONF/lNO38vrPvDDECJcNQCl/35Na59Rqo2TqjZoVY0D5uk5Owm9X83gWuG2iBMuQ5mmjPGsodLZvDd1XPCTUsJyvdbyFzxvwPUSkyr","verification":"EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrw=="}]},{"hash":"0x41846075f4c5aec54d70b476befb97b35696700454b1168e1ae8888d8fb204a3","size":493,"version":0,"nonce":3,"sender":"NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY","sysfee":"11000000","netfee":"4426930","validuntilblock":1200,"attributes":[],"signers":[{"account":"0x95307cb9cc8c4578cef9f6845895eb7aa8be125e","scopes":"CalledByEntry"}],"script":"CwMA6HZIFwAAAAwUqorPhZ1P5AKzTmc/IVaCF5akiOsMFF4Svqh665VYhPb5znhFjMy5fDCVFMAfDAh0cmFuc2ZlcgwUKLOtq3Jp+cIYHbPLdB6/VRkw4nBBYn1bUjk=","witnesses":[{"invocation":"DEA7aJyGTIq0pV20LzVWOCreh6XIxLUCWHVgUFsCTxPOPdqtZBHKnejng3d2BRm/lecTyPLeq7KpRCD9awRvadFWDEBjVZRvSGtGcOEjtUxl4AH5XelYlIUG5k+x3QyYKZtWQc96lUX1hohrNkCmWeWNwC2l8eJGpUxicM+WZGODCVp8DEDbQxvmqRTQ+flc6JetmaqHyw8rfoeQNtmEFpw2cNhyAo5L5Ilp2wbVtJNOJPfw72J7E6FhTK8slIKRqXzpdnyK","verification":"EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrw=="}]}]}]}`,
|
||||
`{"jsonrpc":"2.0","method":"event_missed","params":[]}`,
|
||||
}
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
|
|
|
@ -35,7 +35,7 @@ func NewTransactionOutputRaw(tx *transaction.Transaction, header *block.Header,
|
|||
return result
|
||||
}
|
||||
// confirmations formula
|
||||
confirmations := int(chain.BlockHeight() - header.Base.Index + 1)
|
||||
confirmations := int(chain.BlockHeight() - header.Index + 1)
|
||||
result.TransactionMetadata = TransactionMetadata{
|
||||
Blockhash: header.Hash(),
|
||||
Confirmations: confirmations,
|
||||
|
|
|
@ -60,8 +60,8 @@ type rpcTestCase struct {
|
|||
}
|
||||
|
||||
const testContractHash = "500858b96054d3c302078882c30e76915aac1c83"
|
||||
const deploymentTxHash = "fbea49056332ecf1482568e24ed745151ed3fcacbb59afc22d9baff5346e6257"
|
||||
const genesisBlockHash = "0542f4350c6e236d0509bcd98188b0034bfbecc1a0c7fcdb8e4295310d468b70"
|
||||
const deploymentTxHash = "e5503038c2cd602c100690e266b75e2a9d3dda90a63791fd5ab3008ff053eaae"
|
||||
const genesisBlockHash = "9e7cf6fcfc8d0d6831fac75fa895535a5f1960f45a34754b57bff4d4929635c5"
|
||||
|
||||
const verifyContractHash = "03ffc0897543b9b709e0f8cab4a7682dae0ba943"
|
||||
const verifyContractAVM = "570300412d51083021700c14aa8acf859d4fe402b34e673f2156821796a488ebdb30716813cedb2869db289740"
|
||||
|
@ -1506,7 +1506,7 @@ func (e *executor) getHeader(s string) *block.Header {
|
|||
if err != nil {
|
||||
panic("unknown block (update block hash)")
|
||||
}
|
||||
return block.Header()
|
||||
return &block.Header
|
||||
}
|
||||
|
||||
func encodeBlock(t *testing.T, b *block.Block) string {
|
||||
|
|
|
@ -54,7 +54,7 @@ func (f *feed) Matches(r *response.Notification) bool {
|
|||
case response.BlockEventID:
|
||||
filt := f.filter.(request.BlockFilter)
|
||||
b := r.Payload[0].(*block.Block)
|
||||
return int(b.ConsensusData.PrimaryIndex) == filt.Primary
|
||||
return int(b.PrimaryIndex) == filt.Primary
|
||||
case response.TransactionEventID:
|
||||
filt := f.filter.(request.TxFilter)
|
||||
tx := r.Payload[0].(*transaction.Transaction)
|
||||
|
|
|
@ -306,8 +306,7 @@ func TestFilteredBlockSubscriptions(t *testing.T) {
|
|||
|
||||
require.Equal(t, response.BlockEventID, resp.Event)
|
||||
rmap := resp.Payload[0].(map[string]interface{})
|
||||
cd := rmap["consensusdata"].(map[string]interface{})
|
||||
primary := cd["primary"].(float64)
|
||||
primary := rmap["primary"].(float64)
|
||||
require.Equal(t, 3, int(primary))
|
||||
|
||||
}
|
||||
|
|
BIN
pkg/rpc/server/testdata/testblocks.acc
vendored
BIN
pkg/rpc/server/testdata/testblocks.acc
vendored
Binary file not shown.
|
@ -160,7 +160,7 @@ func addBlock(bc *core.Blockchain, lastBlock *block.Block, script []byte, txs ..
|
|||
func newBlock(bc *core.Blockchain, lastBlock *block.Block, script []byte, txs ...*transaction.Transaction) (*block.Block, error) {
|
||||
witness := transaction.Witness{VerificationScript: script}
|
||||
b := &block.Block{
|
||||
Base: block.Base{
|
||||
Header: block.Header{
|
||||
Network: netmode.UnitTestNet,
|
||||
PrevHash: lastBlock.Hash(),
|
||||
Timestamp: uint64(time.Now().UTC().Unix())*1000 + uint64(lastBlock.Index),
|
||||
|
@ -168,10 +168,6 @@ func newBlock(bc *core.Blockchain, lastBlock *block.Block, script []byte, txs ..
|
|||
NextConsensus: witness.ScriptHash(),
|
||||
Script: witness,
|
||||
},
|
||||
ConsensusData: block.ConsensusData{
|
||||
PrimaryIndex: 0,
|
||||
Nonce: 1111,
|
||||
},
|
||||
Transactions: txs,
|
||||
}
|
||||
if bc.GetConfig().StateRootInHeader {
|
||||
|
|
Loading…
Reference in a new issue