Merge pull request #898 from nspcc-dev/neo3/block_format

core: change block format to neo3
This commit is contained in:
Roman Khimov 2020-04-27 18:10:44 +03:00 committed by GitHub
commit ec2218698f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
41 changed files with 377 additions and 449 deletions

2
go.mod
View file

@ -7,7 +7,7 @@ require (
github.com/go-redis/redis v6.10.2+incompatible github.com/go-redis/redis v6.10.2+incompatible
github.com/go-yaml/yaml v2.1.0+incompatible github.com/go-yaml/yaml v2.1.0+incompatible
github.com/mr-tron/base58 v1.1.2 github.com/mr-tron/base58 v1.1.2
github.com/nspcc-dev/dbft v0.0.0-20200303183127-36d3da79c682 github.com/nspcc-dev/dbft v0.0.0-20200427132226-05feeca847dd
github.com/nspcc-dev/rfc6979 v0.2.0 github.com/nspcc-dev/rfc6979 v0.2.0
github.com/pkg/errors v0.8.1 github.com/pkg/errors v0.8.1
github.com/prometheus/client_golang v1.2.1 github.com/prometheus/client_golang v1.2.1

8
go.sum
View file

@ -131,6 +131,14 @@ github.com/nspcc-dev/dbft v0.0.0-20200219114139-199d286ed6c1 h1:yEx9WznS+rjE0jl0
github.com/nspcc-dev/dbft v0.0.0-20200219114139-199d286ed6c1/go.mod h1:O0qtn62prQSqizzoagHmuuKoz8QMkU3SzBoKdEvm3aQ= github.com/nspcc-dev/dbft v0.0.0-20200219114139-199d286ed6c1/go.mod h1:O0qtn62prQSqizzoagHmuuKoz8QMkU3SzBoKdEvm3aQ=
github.com/nspcc-dev/dbft v0.0.0-20200303183127-36d3da79c682 h1:63OWUolW4GcjJR7cThq8hLnMLTwL+sjO3Qf4fo4sx8w= github.com/nspcc-dev/dbft v0.0.0-20200303183127-36d3da79c682 h1:63OWUolW4GcjJR7cThq8hLnMLTwL+sjO3Qf4fo4sx8w=
github.com/nspcc-dev/dbft v0.0.0-20200303183127-36d3da79c682/go.mod h1:1FYQXSbb6/9HQIkoF8XO7W/S8N7AZRkBsgwbcXRvk0E= github.com/nspcc-dev/dbft v0.0.0-20200303183127-36d3da79c682/go.mod h1:1FYQXSbb6/9HQIkoF8XO7W/S8N7AZRkBsgwbcXRvk0E=
github.com/nspcc-dev/dbft v0.0.0-20200427132226-05feeca847dd h1:4XKbXahJWlhjVx2cETQz9edHQfe3BQ2JjNdvSKFBelY=
github.com/nspcc-dev/dbft v0.0.0-20200427132226-05feeca847dd/go.mod h1:1FYQXSbb6/9HQIkoF8XO7W/S8N7AZRkBsgwbcXRvk0E=
github.com/nspcc-dev/dbft v0.0.0-20200427132226-15a7927772a4 h1:3cFSp4v2u9+S7K1GdLUOP1680EiGEHSBvSI6G2n8XzY=
github.com/nspcc-dev/dbft v0.0.0-20200427132226-15a7927772a4/go.mod h1:1FYQXSbb6/9HQIkoF8XO7W/S8N7AZRkBsgwbcXRvk0E=
github.com/nspcc-dev/dbft v0.0.0-20200427132226-342f23599814 h1:iNqBioi0RU2VX9UiGl/GfQKBbZrDWq5KSxQG+dgTaqo=
github.com/nspcc-dev/dbft v0.0.0-20200427132226-342f23599814/go.mod h1:1FYQXSbb6/9HQIkoF8XO7W/S8N7AZRkBsgwbcXRvk0E=
github.com/nspcc-dev/dbft v0.0.0-20200427132226-660464796c11 h1:sledsmRo0wzgWNCZir5/CeM0PjhHVP8khnGtOfBCFWk=
github.com/nspcc-dev/dbft v0.0.0-20200427132226-660464796c11/go.mod h1:1FYQXSbb6/9HQIkoF8XO7W/S8N7AZRkBsgwbcXRvk0E=
github.com/nspcc-dev/neo-go v0.73.1-pre.0.20200303142215-f5a1b928ce09/go.mod h1:pPYwPZ2ks+uMnlRLUyXOpLieaDQSEaf4NM3zHVbRjmg= github.com/nspcc-dev/neo-go v0.73.1-pre.0.20200303142215-f5a1b928ce09/go.mod h1:pPYwPZ2ks+uMnlRLUyXOpLieaDQSEaf4NM3zHVbRjmg=
github.com/nspcc-dev/neofs-crypto v0.2.0 h1:ftN+59WqxSWz/RCgXYOfhmltOOqU+udsNQSvN6wkFck= github.com/nspcc-dev/neofs-crypto v0.2.0 h1:ftN+59WqxSWz/RCgXYOfhmltOOqU+udsNQSvN6wkFck=
github.com/nspcc-dev/neofs-crypto v0.2.0/go.mod h1:F/96fUzPM3wR+UGsPi3faVNmFlA9KAEAUQR7dMxZmNA= github.com/nspcc-dev/neofs-crypto v0.2.0/go.mod h1:F/96fUzPM3wR+UGsPi3faVNmFlA9KAEAUQR7dMxZmNA=

View file

@ -58,44 +58,23 @@ func (n *neoBlock) SetTransactions(txes []block.Transaction) {
// Version implements block.Block interface. // Version implements block.Block interface.
func (n *neoBlock) Version() uint32 { return n.Block.Version } func (n *neoBlock) Version() uint32 { return n.Block.Version }
// SetVersion implements block.Block interface.
func (n *neoBlock) SetVersion(v uint32) { n.Block.Version = v }
// PrevHash implements block.Block interface. // PrevHash implements block.Block interface.
func (n *neoBlock) PrevHash() util.Uint256 { return n.Block.PrevHash } func (n *neoBlock) PrevHash() util.Uint256 { return n.Block.PrevHash }
// SetPrevHash implements block.Block interface.
func (n *neoBlock) SetPrevHash(h util.Uint256) { n.Block.PrevHash = h }
// MerkleRoot implements block.Block interface. // MerkleRoot implements block.Block interface.
func (n *neoBlock) MerkleRoot() util.Uint256 { return n.Block.MerkleRoot } func (n *neoBlock) MerkleRoot() util.Uint256 { return n.Block.MerkleRoot }
// SetMerkleRoot implements block.Block interface.
func (n *neoBlock) SetMerkleRoot(r util.Uint256) { n.Block.MerkleRoot = r }
// Timestamp implements block.Block interface. // Timestamp implements block.Block interface.
func (n *neoBlock) Timestamp() uint32 { return n.Block.Timestamp } func (n *neoBlock) Timestamp() uint64 { return n.Block.Timestamp * 1000000 }
// SetTimestamp implements block.Block interface.
func (n *neoBlock) SetTimestamp(ts uint32) { n.Block.Timestamp = ts }
// Index implements block.Block interface. // Index implements block.Block interface.
func (n *neoBlock) Index() uint32 { return n.Block.Index } func (n *neoBlock) Index() uint32 { return n.Block.Index }
// SetIndex implements block.Block interface.
func (n *neoBlock) SetIndex(i uint32) { n.Block.Index = i }
// ConsensusData implements block.Block interface. // ConsensusData implements block.Block interface.
func (n *neoBlock) ConsensusData() uint64 { return n.Block.ConsensusData } func (n *neoBlock) ConsensusData() uint64 { return n.Block.ConsensusData.Nonce }
// SetConsensusData implements block.Block interface.
func (n *neoBlock) SetConsensusData(nonce uint64) { n.Block.ConsensusData = nonce }
// NextConsensus implements block.Block interface. // NextConsensus implements block.Block interface.
func (n *neoBlock) NextConsensus() util.Uint160 { return n.Block.NextConsensus } func (n *neoBlock) NextConsensus() util.Uint160 { return n.Block.NextConsensus }
// SetNextConsensus implements block.Block interface.
func (n *neoBlock) SetNextConsensus(h util.Uint160) { n.Block.NextConsensus = h }
// Signature implements block.Block interface. // Signature implements block.Block interface.
func (n *neoBlock) Signature() []byte { return n.signature } func (n *neoBlock) Signature() []byte { return n.signature }

View file

@ -22,28 +22,29 @@ func TestNeoBlock_Sign(t *testing.T) {
func TestNeoBlock_Setters(t *testing.T) { func TestNeoBlock_Setters(t *testing.T) {
b := new(neoBlock) b := new(neoBlock)
b.SetVersion(1) b.Block.Version = 1
require.EqualValues(t, 1, b.Version()) require.EqualValues(t, 1, b.Version())
b.SetIndex(12) b.Block.Index = 12
require.EqualValues(t, 12, b.Index()) require.EqualValues(t, 12, b.Index())
b.SetTimestamp(777) b.Block.Timestamp = 777
require.EqualValues(t, 777, b.Timestamp()) // 777ms -> 777000000ns
require.EqualValues(t, 777000000, b.Timestamp())
b.SetConsensusData(456) b.Block.ConsensusData.Nonce = 456
require.EqualValues(t, 456, b.ConsensusData()) require.EqualValues(t, 456, b.ConsensusData())
b.SetMerkleRoot(util.Uint256{1, 2, 3, 4}) b.Block.MerkleRoot = util.Uint256{1, 2, 3, 4}
require.Equal(t, util.Uint256{1, 2, 3, 4}, b.MerkleRoot()) require.Equal(t, util.Uint256{1, 2, 3, 4}, b.MerkleRoot())
b.SetNextConsensus(util.Uint160{9, 2}) b.Block.NextConsensus = util.Uint160{9, 2}
require.Equal(t, util.Uint160{9, 2}, b.NextConsensus()) require.Equal(t, util.Uint160{9, 2}, b.NextConsensus())
b.SetPrevHash(util.Uint256{9, 8, 7}) b.Block.PrevHash = util.Uint256{9, 8, 7}
require.Equal(t, util.Uint256{9, 8, 7}, b.PrevHash()) require.Equal(t, util.Uint256{9, 8, 7}, b.PrevHash())
txx := []block.Transaction{transaction.NewMinerTX()} txx := []block.Transaction{transaction.NewIssueTX()}
b.SetTransactions(txx) b.SetTransactions(txx)
require.Equal(t, txx, b.Transactions()) require.Equal(t, txx, b.Transactions())
} }

View file

@ -2,15 +2,14 @@ package consensus
import ( import (
"errors" "errors"
"math/rand"
"sort" "sort"
"time" "time"
"github.com/nspcc-dev/dbft" "github.com/nspcc-dev/dbft"
"github.com/nspcc-dev/dbft/block" "github.com/nspcc-dev/dbft/block"
"github.com/nspcc-dev/dbft/crypto" "github.com/nspcc-dev/dbft/crypto"
"github.com/nspcc-dev/dbft/merkle"
"github.com/nspcc-dev/dbft/payload" "github.com/nspcc-dev/dbft/payload"
"github.com/nspcc-dev/neo-go/pkg/core"
coreb "github.com/nspcc-dev/neo-go/pkg/core/block" coreb "github.com/nspcc-dev/neo-go/pkg/core/block"
"github.com/nspcc-dev/neo-go/pkg/core/blockchainer" "github.com/nspcc-dev/neo-go/pkg/core/blockchainer"
"github.com/nspcc-dev/neo-go/pkg/core/mempool" "github.com/nspcc-dev/neo-go/pkg/core/mempool"
@ -136,7 +135,7 @@ func NewService(cfg Config) (Service, error) {
dbft.WithVerifyBlock(srv.verifyBlock), dbft.WithVerifyBlock(srv.verifyBlock),
dbft.WithGetBlock(srv.getBlock), dbft.WithGetBlock(srv.getBlock),
dbft.WithWatchOnly(func() bool { return false }), dbft.WithWatchOnly(func() bool { return false }),
dbft.WithNewBlock(func() block.Block { return new(neoBlock) }), dbft.WithNewBlockFromContext(newBlockFromContext),
dbft.WithCurrentHeight(cfg.Chain.BlockHeight), dbft.WithCurrentHeight(cfg.Chain.BlockHeight),
dbft.WithCurrentBlockHash(cfg.Chain.CurrentBlockHash), dbft.WithCurrentBlockHash(cfg.Chain.CurrentBlockHash),
dbft.WithGetValidators(srv.getValidators), dbft.WithGetValidators(srv.getValidators),
@ -276,7 +275,6 @@ func (s *service) OnPayload(cp *Payload) {
switch cp.Type() { switch cp.Type() {
case payload.PrepareRequestType: case payload.PrepareRequestType:
req := cp.GetPrepareRequest().(*prepareRequest) req := cp.GetPrepareRequest().(*prepareRequest)
s.txx.Add(&req.minerTx)
s.lastProposal = req.transactionHashes s.lastProposal = req.transactionHashes
} }
@ -316,12 +314,6 @@ func (s *service) GetPayload(h util.Uint256) *Payload {
} }
func (s *service) broadcast(p payload.ConsensusPayload) { func (s *service) broadcast(p payload.ConsensusPayload) {
switch p.Type() {
case payload.PrepareRequestType:
pr := p.GetPrepareRequest().(*prepareRequest)
pr.minerTx = *s.txx.Get(pr.transactionHashes[0]).(*transaction.Transaction)
}
if err := p.(*Payload).Sign(s.dbft.Priv.(*privateKey)); err != nil { if err := p.(*Payload).Sign(s.dbft.Priv.(*privateKey)); err != nil {
s.log.Warn("can't sign consensus payload", zap.Error(err)) s.log.Warn("can't sign consensus payload", zap.Error(err))
} }
@ -442,40 +434,11 @@ func (s *service) getVerifiedTx(count int) []block.Transaction {
txx = s.Config.Chain.ApplyPolicyToTxSet(txx) txx = s.Config.Chain.ApplyPolicyToTxSet(txx)
} }
res := make([]block.Transaction, len(txx)+1) res := make([]block.Transaction, len(txx))
var netFee util.Fixed8
for i := range txx { for i := range txx {
res[i+1] = txx[i].Tx res[i] = txx[i].Tx
netFee += txx[i].Fee
} }
var txOuts []transaction.Output
if netFee != 0 {
sh := s.wallet.GetChangeAddress()
if sh.Equals(util.Uint160{}) {
pk := s.dbft.Pub.(*publicKey)
sh = pk.GetScriptHash()
}
txOuts = []transaction.Output{{
AssetID: core.UtilityTokenID(),
Amount: netFee,
ScriptHash: sh,
}}
}
for {
minerTx := transaction.NewMinerTX()
minerTx.Outputs = txOuts
minerTx.ValidUntilBlock = s.dbft.BlockIndex
minerTx.Nonce = rand.Uint32()
res[0] = minerTx
if tx, _, _ := s.Chain.GetTransaction(res[0].Hash()); tx == nil {
break
}
}
s.txx.Add(res[0])
return res return res
} }
@ -516,3 +479,30 @@ func convertKeys(validators []crypto.PublicKey) (pubs []*keys.PublicKey) {
return return
} }
func newBlockFromContext(ctx *dbft.Context) block.Block {
block := new(neoBlock)
if ctx.TransactionHashes == nil {
return nil
}
block.Block.Timestamp = ctx.Timestamp / 1000000
block.Block.Index = ctx.BlockIndex
block.Block.NextConsensus = ctx.NextConsensus
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
consensusData := coreb.ConsensusData{
PrimaryIndex: primaryIndex,
Nonce: ctx.Nonce,
}
if len(ctx.TransactionHashes) != 0 {
mt := merkle.NewMerkleTree(append([]util.Uint256{consensusData.Hash()}, ctx.TransactionHashes...)...)
block.Block.MerkleRoot = mt.Root().Hash
}
return block
}

View file

@ -22,7 +22,7 @@ import (
func TestNewService(t *testing.T) { func TestNewService(t *testing.T) {
srv := newTestService(t) srv := newTestService(t)
tx := transaction.NewMinerTX() tx := transaction.NewContractTX()
tx.ValidUntilBlock = 1 tx.ValidUntilBlock = 1
addSender(t, tx) addSender(t, tx)
signTx(t, tx) signTx(t, tx)
@ -30,8 +30,8 @@ func TestNewService(t *testing.T) {
var txx []block.Transaction var txx []block.Transaction
require.NotPanics(t, func() { txx = srv.getVerifiedTx(1) }) require.NotPanics(t, func() { txx = srv.getVerifiedTx(1) })
require.Len(t, txx, 2) require.Len(t, txx, 1)
require.Equal(t, tx, txx[1]) require.Equal(t, tx, txx[0])
srv.Chain.Close() srv.Chain.Close()
} }
@ -39,7 +39,8 @@ func TestService_GetVerified(t *testing.T) {
srv := newTestService(t) srv := newTestService(t)
var txs []*transaction.Transaction var txs []*transaction.Transaction
for i := 0; i < 4; i++ { for i := 0; i < 4; i++ {
tx := transaction.NewMinerTXWithNonce(123 + uint32(i)) tx := transaction.NewContractTX()
tx.Nonce = 123 + uint32(i)
tx.ValidUntilBlock = 1 tx.ValidUntilBlock = 1
txs = append(txs, tx) txs = append(txs, tx)
} }
@ -52,7 +53,9 @@ func TestService_GetVerified(t *testing.T) {
p := new(Payload) p := new(Payload)
p.message = &message{} p.message = &message{}
p.SetType(payload.PrepareRequestType) p.SetType(payload.PrepareRequestType)
p.SetPayload(&prepareRequest{transactionHashes: hashes, minerTx: *transaction.NewMinerTXWithNonce(999)}) tx := transaction.NewContractTX()
tx.Nonce = 999
p.SetPayload(&prepareRequest{transactionHashes: hashes})
p.SetValidatorIndex(1) p.SetValidatorIndex(1)
priv, _ := getTestValidator(1) priv, _ := getTestValidator(1)
@ -65,8 +68,8 @@ func TestService_GetVerified(t *testing.T) {
t.Run("new transactions will be proposed in case of failure", func(t *testing.T) { t.Run("new transactions will be proposed in case of failure", func(t *testing.T) {
txx := srv.getVerifiedTx(10) txx := srv.getVerifiedTx(10)
require.Equal(t, 2, len(txx), "there is only 1 tx in mempool") require.Equal(t, 1, len(txx), "there is only 1 tx in mempool")
require.Equal(t, txs[3], txx[1]) require.Equal(t, txs[3], txx[0])
}) })
t.Run("more than half of the last proposal will be reused", func(t *testing.T) { t.Run("more than half of the last proposal will be reused", func(t *testing.T) {
@ -117,7 +120,8 @@ func TestService_getTx(t *testing.T) {
srv := newTestService(t) srv := newTestService(t)
t.Run("transaction in mempool", func(t *testing.T) { t.Run("transaction in mempool", func(t *testing.T) {
tx := transaction.NewMinerTXWithNonce(1234) tx := transaction.NewContractTX()
tx.Nonce = 1234
tx.ValidUntilBlock = 1 tx.ValidUntilBlock = 1
addSender(t, tx) addSender(t, tx)
signTx(t, tx) signTx(t, tx)
@ -133,7 +137,8 @@ func TestService_getTx(t *testing.T) {
}) })
t.Run("transaction in local cache", func(t *testing.T) { t.Run("transaction in local cache", func(t *testing.T) {
tx := transaction.NewMinerTXWithNonce(4321) tx := transaction.NewContractTX()
tx.Nonce = 4321
tx.ValidUntilBlock = 1 tx.ValidUntilBlock = 1
h := tx.Hash() h := tx.Hash()

View file

@ -243,14 +243,12 @@ func randomPrepareRequest(t *testing.T) *prepareRequest {
const txCount = 3 const txCount = 3
req := &prepareRequest{ req := &prepareRequest{
timestamp: rand.Uint32(), timestamp: rand.Uint64(),
nonce: rand.Uint64(), nonce: rand.Uint64(),
transactionHashes: make([]util.Uint256, txCount), transactionHashes: make([]util.Uint256, txCount),
minerTx: *transaction.NewMinerTX(),
} }
req.transactionHashes[0] = req.minerTx.Hash() for i := 0; i < txCount; i++ {
for i := 1; i < txCount; i++ {
req.transactionHashes[i] = random.Uint256() req.transactionHashes[i] = random.Uint256()
} }
req.nextConsensus = random.Uint160() req.nextConsensus = random.Uint160()

View file

@ -2,17 +2,15 @@ package consensus
import ( import (
"github.com/nspcc-dev/dbft/payload" "github.com/nspcc-dev/dbft/payload"
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
"github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/io"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
) )
// prepareRequest represents dBFT prepareRequest message. // prepareRequest represents dBFT prepareRequest message.
type prepareRequest struct { type prepareRequest struct {
timestamp uint32 timestamp uint64
nonce uint64 nonce uint64
transactionHashes []util.Uint256 transactionHashes []util.Uint256
minerTx transaction.Transaction
nextConsensus util.Uint160 nextConsensus util.Uint160
} }
@ -20,27 +18,25 @@ var _ payload.PrepareRequest = (*prepareRequest)(nil)
// EncodeBinary implements io.Serializable interface. // EncodeBinary implements io.Serializable interface.
func (p *prepareRequest) EncodeBinary(w *io.BinWriter) { func (p *prepareRequest) EncodeBinary(w *io.BinWriter) {
w.WriteU32LE(p.timestamp) w.WriteU64LE(p.timestamp)
w.WriteU64LE(p.nonce) w.WriteU64LE(p.nonce)
w.WriteBytes(p.nextConsensus[:]) w.WriteBytes(p.nextConsensus[:])
w.WriteArray(p.transactionHashes) w.WriteArray(p.transactionHashes)
p.minerTx.EncodeBinary(w)
} }
// DecodeBinary implements io.Serializable interface. // DecodeBinary implements io.Serializable interface.
func (p *prepareRequest) DecodeBinary(r *io.BinReader) { func (p *prepareRequest) DecodeBinary(r *io.BinReader) {
p.timestamp = r.ReadU32LE() p.timestamp = r.ReadU64LE()
p.nonce = r.ReadU64LE() p.nonce = r.ReadU64LE()
r.ReadBytes(p.nextConsensus[:]) r.ReadBytes(p.nextConsensus[:])
r.ReadArray(&p.transactionHashes) r.ReadArray(&p.transactionHashes)
p.minerTx.DecodeBinary(r)
} }
// Timestamp implements payload.PrepareRequest interface. // Timestamp implements payload.PrepareRequest interface.
func (p *prepareRequest) Timestamp() uint32 { return p.timestamp } func (p *prepareRequest) Timestamp() uint64 { return p.timestamp * 1000000 }
// SetTimestamp implements payload.PrepareRequest interface. // SetTimestamp implements payload.PrepareRequest interface.
func (p *prepareRequest) SetTimestamp(ts uint32) { p.timestamp = ts } func (p *prepareRequest) SetTimestamp(ts uint64) { p.timestamp = ts / 1000000 }
// Nonce implements payload.PrepareRequest interface. // Nonce implements payload.PrepareRequest interface.
func (p *prepareRequest) Nonce() uint64 { return p.nonce } func (p *prepareRequest) Nonce() uint64 { return p.nonce }

View file

@ -12,7 +12,12 @@ func TestPrepareRequest_Setters(t *testing.T) {
var p prepareRequest var p prepareRequest
p.SetTimestamp(123) p.SetTimestamp(123)
require.EqualValues(t, 123, p.Timestamp()) // 123ns -> 0ms -> 0ns
require.EqualValues(t, 0, p.Timestamp())
p.SetTimestamp(1230000)
// 1230000ns -> 1ms -> 1000000ns
require.EqualValues(t, 1000000, p.Timestamp())
p.SetNextConsensus(util.Uint160{5, 6, 7}) p.SetNextConsensus(util.Uint160{5, 6, 7})
require.Equal(t, util.Uint160{5, 6, 7}, p.NextConsensus()) require.Equal(t, util.Uint160{5, 6, 7}, p.NextConsensus())

View file

@ -5,7 +5,6 @@ import (
"github.com/nspcc-dev/dbft/crypto" "github.com/nspcc-dev/dbft/crypto"
"github.com/nspcc-dev/dbft/payload" "github.com/nspcc-dev/dbft/payload"
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -32,7 +31,6 @@ func TestRecoveryMessage_Setters(t *testing.T) {
timestamp: 87, timestamp: 87,
nonce: 321, nonce: 321,
transactionHashes: []util.Uint256{{1}}, transactionHashes: []util.Uint256{{1}},
minerTx: *transaction.NewMinerTX(),
nextConsensus: util.Uint160{1, 2}, nextConsensus: util.Uint160{1, 2},
} }
p1 := new(Payload) p1 := new(Payload)

View file

@ -2,7 +2,6 @@ package block
import ( import (
"errors" "errors"
"fmt"
"github.com/Workiva/go-datastructures/queue" "github.com/Workiva/go-datastructures/queue"
"github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/core/transaction"
@ -16,6 +15,9 @@ type Block struct {
// The base of the block. // The base of the block.
Base Base
// Primary index and nonce
ConsensusData ConsensusData `json:"consensus_data"`
// Transaction list. // Transaction list.
Transactions []*transaction.Transaction `json:"tx"` Transactions []*transaction.Transaction `json:"tx"`
@ -30,10 +32,12 @@ func (b *Block) Header() *Header {
} }
} }
func merkleTreeFromTransactions(txes []*transaction.Transaction) (*hash.MerkleTree, error) { // computeMerkleTree computes Merkle tree based on actual block's data.
hashes := make([]util.Uint256, len(txes)) func (b *Block) computeMerkleTree() (*hash.MerkleTree, error) {
for i, tx := range txes { hashes := make([]util.Uint256, len(b.Transactions)+1)
hashes[i] = tx.Hash() hashes[0] = b.ConsensusData.Hash()
for i, tx := range b.Transactions {
hashes[i+1] = tx.Hash()
} }
return hash.NewMerkleTree(hashes) return hash.NewMerkleTree(hashes)
@ -41,7 +45,7 @@ func merkleTreeFromTransactions(txes []*transaction.Transaction) (*hash.MerkleTr
// RebuildMerkleRoot rebuilds the merkleroot of the block. // RebuildMerkleRoot rebuilds the merkleroot of the block.
func (b *Block) RebuildMerkleRoot() error { func (b *Block) RebuildMerkleRoot() error {
merkle, err := merkleTreeFromTransactions(b.Transactions) merkle, err := b.computeMerkleTree()
if err != nil { if err != nil {
return err return err
} }
@ -52,21 +56,18 @@ func (b *Block) RebuildMerkleRoot() error {
// Verify verifies the integrity of the block. // Verify verifies the integrity of the block.
func (b *Block) Verify() error { func (b *Block) Verify() error {
// There has to be some transaction inside. if b.Transactions != nil {
if len(b.Transactions) == 0 { hashes := map[util.Uint256]bool{}
return errors.New("no transactions") for _, tx := range b.Transactions {
} if !hashes[tx.Hash()] {
// The first TX has to be a miner transaction. hashes[tx.Hash()] = true
if b.Transactions[0].Type != transaction.MinerType { } else {
return fmt.Errorf("the first transaction is %s", b.Transactions[0].Type) return errors.New("transaction duplication is not allowed")
}
// If the first TX is a minerTX then all others cant.
for _, tx := range b.Transactions[1:] {
if tx.Type == transaction.MinerType {
return fmt.Errorf("miner transaction %s is not the first one", tx.Hash().StringLE())
} }
} }
merkle, err := merkleTreeFromTransactions(b.Transactions) }
merkle, err := b.computeMerkleTree()
if err != nil { if err != nil {
return err return err
} }
@ -92,13 +93,19 @@ func NewBlockFromTrimmedBytes(b []byte) (*Block, error) {
block.Script.DecodeBinary(br) block.Script.DecodeBinary(br)
lenTX := br.ReadVarUint() lenHashes := br.ReadVarUint()
if lenHashes > 0 {
var consensusDataHash util.Uint256
consensusDataHash.DecodeBinary(br)
lenTX := lenHashes - 1
block.Transactions = make([]*transaction.Transaction, lenTX) block.Transactions = make([]*transaction.Transaction, lenTX)
for i := 0; i < int(lenTX); i++ { for i := 0; i < int(lenTX); i++ {
var hash util.Uint256 var hash util.Uint256
hash.DecodeBinary(br) hash.DecodeBinary(br)
block.Transactions[i] = transaction.NewTrimmedTX(hash) block.Transactions[i] = transaction.NewTrimmedTX(hash)
} }
block.ConsensusData.DecodeBinary(br)
}
return block, br.Err return block, br.Err
} }
@ -112,14 +119,20 @@ func (b *Block) Trim() ([]byte, error) {
buf.WriteB(1) buf.WriteB(1)
b.Script.EncodeBinary(buf.BinWriter) b.Script.EncodeBinary(buf.BinWriter)
buf.WriteVarUint(uint64(len(b.Transactions))) buf.WriteVarUint(uint64(len(b.Transactions)) + 1)
hash := b.ConsensusData.Hash()
hash.EncodeBinary(buf.BinWriter)
for _, tx := range b.Transactions { for _, tx := range b.Transactions {
h := tx.Hash() h := tx.Hash()
h.EncodeBinary(buf.BinWriter) h.EncodeBinary(buf.BinWriter)
} }
b.ConsensusData.EncodeBinary(buf.BinWriter)
if buf.Err != nil { if buf.Err != nil {
return nil, buf.Err return nil, buf.Err
} }
return buf.Bytes(), nil return buf.Bytes(), nil
} }
@ -127,14 +140,31 @@ func (b *Block) Trim() ([]byte, error) {
// Serializable interface. // Serializable interface.
func (b *Block) DecodeBinary(br *io.BinReader) { func (b *Block) DecodeBinary(br *io.BinReader) {
b.Base.DecodeBinary(br) b.Base.DecodeBinary(br)
br.ReadArray(&b.Transactions) contentsCount := br.ReadVarUint()
if contentsCount == 0 {
br.Err = errors.New("invalid block format")
return
}
b.ConsensusData.DecodeBinary(br)
txes := make([]*transaction.Transaction, contentsCount-1)
for i := 0; i < int(contentsCount)-1; i++ {
tx := new(transaction.Transaction)
tx.DecodeBinary(br)
txes[i] = tx
}
b.Transactions = txes
br.Err = b.Verify()
} }
// EncodeBinary encodes the block to the given BinWriter, implementing // EncodeBinary encodes the block to the given BinWriter, implementing
// Serializable interface. // Serializable interface.
func (b *Block) EncodeBinary(bw *io.BinWriter) { func (b *Block) EncodeBinary(bw *io.BinWriter) {
b.Base.EncodeBinary(bw) b.Base.EncodeBinary(bw)
bw.WriteArray(b.Transactions) bw.WriteVarUint(uint64(len(b.Transactions) + 1))
b.ConsensusData.EncodeBinary(bw)
for i := 0; i < len(b.Transactions); i++ {
b.Transactions[i].EncodeBinary(bw)
}
} }
// Compare implements the queue Item interface. // Compare implements the queue Item interface.

View file

@ -20,17 +20,15 @@ type Base struct {
// Root hash of a transaction list. // Root hash of a transaction list.
MerkleRoot util.Uint256 `json:"merkleroot"` MerkleRoot util.Uint256 `json:"merkleroot"`
// Timestamp is a millisecond-precision timestamp.
// The time stamp of each block must be later than previous block's time stamp. // 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. // 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. // The height of the block must be exactly equal to the height of the previous block plus 1.
Timestamp uint32 `json:"time"` Timestamp uint64 `json:"time"`
// index/height of the block // index/height of the block
Index uint32 `json:"height"` Index uint32 `json:"height"`
// Random number also called nonce
ConsensusData uint64 `json:"nonce"`
// Contract address of the next miner // Contract address of the next miner
NextConsensus util.Uint160 `json:"next_consensus"` NextConsensus util.Uint160 `json:"next_consensus"`
@ -117,9 +115,8 @@ func (b *Base) encodeHashableFields(bw *io.BinWriter) {
bw.WriteU32LE(b.Version) bw.WriteU32LE(b.Version)
bw.WriteBytes(b.PrevHash[:]) bw.WriteBytes(b.PrevHash[:])
bw.WriteBytes(b.MerkleRoot[:]) bw.WriteBytes(b.MerkleRoot[:])
bw.WriteU32LE(b.Timestamp) bw.WriteU64LE(b.Timestamp)
bw.WriteU32LE(b.Index) bw.WriteU32LE(b.Index)
bw.WriteU64LE(b.ConsensusData)
bw.WriteBytes(b.NextConsensus[:]) bw.WriteBytes(b.NextConsensus[:])
} }
@ -129,9 +126,8 @@ func (b *Base) decodeHashableFields(br *io.BinReader) {
b.Version = br.ReadU32LE() b.Version = br.ReadU32LE()
br.ReadBytes(b.PrevHash[:]) br.ReadBytes(b.PrevHash[:])
br.ReadBytes(b.MerkleRoot[:]) br.ReadBytes(b.MerkleRoot[:])
b.Timestamp = br.ReadU32LE() b.Timestamp = br.ReadU64LE()
b.Index = br.ReadU32LE() b.Index = br.ReadU32LE()
b.ConsensusData = br.ReadU64LE()
br.ReadBytes(b.NextConsensus[:]) br.ReadBytes(b.NextConsensus[:])
// Make the hash of the block here so we dont need to do this // Make the hash of the block here so we dont need to do this

View file

@ -71,17 +71,19 @@ func newDumbBlock() *Block {
Version: 0, Version: 0,
PrevHash: hash.Sha256([]byte("a")), PrevHash: hash.Sha256([]byte("a")),
MerkleRoot: hash.Sha256([]byte("b")), MerkleRoot: hash.Sha256([]byte("b")),
Timestamp: uint32(100500), Timestamp: 100500,
Index: 1, Index: 1,
ConsensusData: 1111,
NextConsensus: hash.Hash160([]byte("a")), NextConsensus: hash.Hash160([]byte("a")),
Script: transaction.Witness{ Script: transaction.Witness{
VerificationScript: []byte{0x51}, // PUSH1 VerificationScript: []byte{0x51}, // PUSH1
InvocationScript: []byte{0x61}, // NOP InvocationScript: []byte{0x61}, // NOP
}, },
}, },
ConsensusData: ConsensusData{
PrimaryIndex: 0,
Nonce: 1111,
},
Transactions: []*transaction.Transaction{ Transactions: []*transaction.Transaction{
transaction.NewMinerTX(),
transaction.NewIssueTX(), transaction.NewIssueTX(),
}, },
} }
@ -99,25 +101,9 @@ func TestBlockVerify(t *testing.T) {
assert.Nil(t, block.RebuildMerkleRoot()) assert.Nil(t, block.RebuildMerkleRoot())
assert.Nil(t, block.Verify()) assert.Nil(t, block.Verify())
block.Transactions = []*transaction.Transaction{ block.Transactions = []*transaction.Transaction{}
transaction.NewIssueTX(),
transaction.NewMinerTX(),
}
assert.NoError(t, block.RebuildMerkleRoot()) assert.NoError(t, block.RebuildMerkleRoot())
assert.NotNil(t, block.Verify()) assert.Nil(t, block.Verify())
block.Transactions = []*transaction.Transaction{
transaction.NewIssueTX(),
transaction.NewMinerTX(),
}
assert.NoError(t, block.RebuildMerkleRoot())
assert.NotNil(t, block.Verify())
block.Transactions = []*transaction.Transaction{
transaction.NewMinerTX(),
transaction.NewIssueTX(),
transaction.NewIssueTX(),
}
assert.NotNil(t, block.Verify())
} }
//TODO NEO3.0: Update binary //TODO NEO3.0: Update binary

View file

@ -0,0 +1,52 @@
package block
import (
"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 `json:"primary"`
// Random number
Nonce uint64 `json:"nonce"`
// Hash of the ConsensusData (single SHA256)
hash util.Uint256
}
// 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.Sha256(b)
return nil
}

View file

@ -16,9 +16,8 @@ func TestHeaderEncodeDecode(t *testing.T) {
Version: 0, Version: 0,
PrevHash: hash.Sha256([]byte("prevhash")), PrevHash: hash.Sha256([]byte("prevhash")),
MerkleRoot: hash.Sha256([]byte("merkleroot")), MerkleRoot: hash.Sha256([]byte("merkleroot")),
Timestamp: uint32(time.Now().UTC().Unix()), Timestamp: uint64(time.Now().UTC().Unix() * 1000),
Index: 3445, Index: 3445,
ConsensusData: 394949,
NextConsensus: util.Uint160{}, NextConsensus: util.Uint160{},
Script: transaction.Witness{ Script: transaction.Witness{
InvocationScript: []byte{0x10}, InvocationScript: []byte{0x10},
@ -34,7 +33,6 @@ func TestHeaderEncodeDecode(t *testing.T) {
assert.Equal(t, header.PrevHash, headerDecode.PrevHash, "expected both prev hashes to be equal") assert.Equal(t, header.PrevHash, headerDecode.PrevHash, "expected both prev hashes to be equal")
assert.Equal(t, header.MerkleRoot, headerDecode.MerkleRoot, "expected both merkle roots to be equal") assert.Equal(t, header.MerkleRoot, headerDecode.MerkleRoot, "expected both merkle roots to be equal")
assert.Equal(t, header.Index, headerDecode.Index, "expected both indexes to be equal") assert.Equal(t, header.Index, headerDecode.Index, "expected both indexes to be equal")
assert.Equal(t, header.ConsensusData, headerDecode.ConsensusData, "expected both consensus data fields to be equal")
assert.Equal(t, header.NextConsensus, headerDecode.NextConsensus, "expected both next consensus fields to be equal") assert.Equal(t, header.NextConsensus, headerDecode.NextConsensus, "expected both next consensus fields to be equal")
assert.Equal(t, header.Script.InvocationScript, headerDecode.Script.InvocationScript, "expected equal invocation scripts") assert.Equal(t, header.Script.InvocationScript, headerDecode.Script.InvocationScript, "expected equal invocation scripts")
assert.Equal(t, header.Script.VerificationScript, headerDecode.Script.VerificationScript, "expected equal verification scripts") assert.Equal(t, header.Script.VerificationScript, headerDecode.Script.VerificationScript, "expected equal verification scripts")

View file

@ -914,9 +914,6 @@ func (bc *Blockchain) GetBlock(hash util.Uint256) (*block.Block, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
if len(block.Transactions) == 0 {
return nil, fmt.Errorf("only header is available")
}
for _, tx := range block.Transactions { for _, tx := range block.Transactions {
stx, _, err := bc.dao.GetTransaction(tx.Hash()) stx, _, err := bc.dao.GetTransaction(tx.Hash())
if err != nil { if err != nil {
@ -1118,7 +1115,7 @@ func (bc *Blockchain) FeePerByte(t *transaction.Transaction) util.Fixed8 {
// NetworkFee returns network fee. // NetworkFee returns network fee.
func (bc *Blockchain) NetworkFee(t *transaction.Transaction) util.Fixed8 { func (bc *Blockchain) NetworkFee(t *transaction.Transaction) util.Fixed8 {
// https://github.com/neo-project/neo/blob/master-2.x/neo/Network/P2P/Payloads/ClaimTransaction.cs#L16 // https://github.com/neo-project/neo/blob/master-2.x/neo/Network/P2P/Payloads/ClaimTransaction.cs#L16
if t.Type == transaction.ClaimType || t.Type == transaction.MinerType { if t.Type == transaction.ClaimType {
return 0 return 0
} }
@ -1455,7 +1452,7 @@ func (bc *Blockchain) verifyResults(t *transaction.Transaction, results []*trans
} }
switch t.Type { switch t.Type {
case transaction.MinerType, transaction.ClaimType: case transaction.ClaimType:
for _, r := range resultsIssue { for _, r := range resultsIssue {
if r.AssetID != UtilityTokenID() { if r.AssetID != UtilityTokenID() {
return errors.New("miner or claim tx issues non-utility tokens") return errors.New("miner or claim tx issues non-utility tokens")

View file

@ -97,7 +97,7 @@ func TestScriptFromWitness(t *testing.T) {
func TestGetHeader(t *testing.T) { func TestGetHeader(t *testing.T) {
bc := newTestChain(t) bc := newTestChain(t)
tx := transaction.NewMinerTX() tx := transaction.NewContractTX()
tx.ValidUntilBlock = bc.BlockHeight() + 1 tx.ValidUntilBlock = bc.BlockHeight() + 1
assert.Nil(t, addSender(tx)) assert.Nil(t, addSender(tx))
assert.Nil(t, signTx(bc, tx)) assert.Nil(t, signTx(bc, tx))

View file

@ -61,12 +61,15 @@ func newBlock(cfg config.ProtocolConfiguration, index uint32, prev util.Uint256,
Base: block.Base{ Base: block.Base{
Version: 0, Version: 0,
PrevHash: prev, PrevHash: prev,
Timestamp: uint32(time.Now().UTC().Unix()) + index, Timestamp: uint64(time.Now().UTC().Unix()) + uint64(index),
Index: index, Index: index,
ConsensusData: 1111,
NextConsensus: witness.ScriptHash(), NextConsensus: witness.ScriptHash(),
Script: witness, Script: witness,
}, },
ConsensusData: block.ConsensusData{
PrimaryIndex: 0,
Nonce: 1111,
},
Transactions: txs, Transactions: txs,
} }
_ = b.RebuildMerkleRoot() _ = b.RebuildMerkleRoot()
@ -80,17 +83,7 @@ func (bc *Blockchain) genBlocks(n int) ([]*block.Block, error) {
lastHash := bc.topBlock.Load().(*block.Block).Hash() lastHash := bc.topBlock.Load().(*block.Block).Hash()
lastIndex := bc.topBlock.Load().(*block.Block).Index lastIndex := bc.topBlock.Load().(*block.Block).Index
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
minerTx := transaction.NewMinerTXWithNonce(uint32(1234 + i)) blocks[i] = newBlock(bc.config, uint32(i)+lastIndex+1, lastHash)
minerTx.ValidUntilBlock = lastIndex + uint32(i) + 1
err := addSender(minerTx)
if err != nil {
return nil, err
}
err = signTx(bc, minerTx)
if err != nil {
return nil, err
}
blocks[i] = newBlock(bc.config, uint32(i)+lastIndex+1, lastHash, minerTx)
if err := bc.AddBlock(blocks[i]); err != nil { if err := bc.AddBlock(blocks[i]); err != nil {
return blocks, err return blocks, err
} }
@ -130,17 +123,19 @@ func newDumbBlock() *block.Block {
Version: 0, Version: 0,
PrevHash: hash.Sha256([]byte("a")), PrevHash: hash.Sha256([]byte("a")),
MerkleRoot: hash.Sha256([]byte("b")), MerkleRoot: hash.Sha256([]byte("b")),
Timestamp: uint32(100500), Timestamp: 100500,
Index: 1, Index: 1,
ConsensusData: 1111,
NextConsensus: hash.Hash160([]byte("a")), NextConsensus: hash.Hash160([]byte("a")),
Script: transaction.Witness{ Script: transaction.Witness{
VerificationScript: []byte{0x51}, // PUSH1 VerificationScript: []byte{0x51}, // PUSH1
InvocationScript: []byte{0x61}, // NOP InvocationScript: []byte{0x61}, // NOP
}, },
}, },
ConsensusData: block.ConsensusData{
PrimaryIndex: 0,
Nonce: 1111,
},
Transactions: []*transaction.Transaction{ Transactions: []*transaction.Transaction{
{Type: transaction.MinerType},
{Type: transaction.IssueType}, {Type: transaction.IssueType},
}, },
} }
@ -175,13 +170,6 @@ func TestCreateBasicChain(t *testing.T) {
return testNonce return testNonce
} }
// Creates new miner tx with specified validUntilBlock field
nextMinerTx := func(validUntilBlock uint32) *transaction.Transaction {
minerTx := transaction.NewMinerTXWithNonce(getNextNonce())
minerTx.ValidUntilBlock = validUntilBlock
return minerTx
}
var neoAmount = util.Fixed8FromInt64(99999000) var neoAmount = util.Fixed8FromInt64(99999000)
var neoRemainder = util.Fixed8FromInt64(100000000) - neoAmount var neoRemainder = util.Fixed8FromInt64(100000000) - neoAmount
bc := newTestChain(t) bc := newTestChain(t)
@ -195,8 +183,8 @@ func TestCreateBasicChain(t *testing.T) {
// use output of issue tx from genesis block as an input // use output of issue tx from genesis block as an input
genesisBlock, err := bc.GetBlock(bc.GetHeaderHash(0)) genesisBlock, err := bc.GetBlock(bc.GetHeaderHash(0))
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, 5, len(genesisBlock.Transactions)) require.Equal(t, 4, len(genesisBlock.Transactions))
h := genesisBlock.Transactions[3].Hash() h := genesisBlock.Transactions[2].Hash()
txMoveNeo.AddInput(&transaction.Input{ txMoveNeo.AddInput(&transaction.Input{
PrevHash: h, PrevHash: h,
PrevIndex: 0, PrevIndex: 0,
@ -219,12 +207,8 @@ func TestCreateBasicChain(t *testing.T) {
Position: 1, Position: 1,
}) })
txMoveNeo.Data = new(transaction.ContractTX) txMoveNeo.Data = new(transaction.ContractTX)
require.NoError(t, signTx(bc, txMoveNeo))
minerTx := nextMinerTx(validUntilBlock) b := bc.newBlock(txMoveNeo)
minerTx.Sender = neoOwner
require.NoError(t, signTx(bc, minerTx, txMoveNeo))
b := bc.newBlock(minerTx, txMoveNeo)
require.NoError(t, bc.AddBlock(b)) require.NoError(t, bc.AddBlock(b))
t.Logf("txMoveNeo: %s", txMoveNeo.Hash().StringLE()) t.Logf("txMoveNeo: %s", txMoveNeo.Hash().StringLE())
@ -258,10 +242,7 @@ func TestCreateBasicChain(t *testing.T) {
}) })
txNeoRound.Data = new(transaction.ContractTX) txNeoRound.Data = new(transaction.ContractTX)
require.NoError(t, acc0.SignTx(txNeoRound)) require.NoError(t, acc0.SignTx(txNeoRound))
minerTx = nextMinerTx(validUntilBlock) b = bc.newBlock(txNeoRound)
minerTx.Sender = priv0ScriptHash
require.NoError(t, acc0.SignTx(minerTx))
b = bc.newBlock(minerTx, txNeoRound)
require.NoError(t, bc.AddBlock(b)) require.NoError(t, bc.AddBlock(b))
t.Logf("txNeoRound: %s", txNeoRound.Hash().StringLE()) t.Logf("txNeoRound: %s", txNeoRound.Hash().StringLE())
@ -285,10 +266,7 @@ func TestCreateBasicChain(t *testing.T) {
Position: 0, Position: 0,
}) })
require.NoError(t, acc0.SignTx(txClaim)) require.NoError(t, acc0.SignTx(txClaim))
minerTx = nextMinerTx(validUntilBlock) b = bc.newBlock(txClaim)
minerTx.Sender = priv0ScriptHash
require.NoError(t, acc0.SignTx(minerTx))
b = bc.newBlock(minerTx, txClaim)
require.NoError(t, bc.AddBlock(b)) require.NoError(t, bc.AddBlock(b))
t.Logf("txClaim: %s", txClaim.Hash().StringLE()) t.Logf("txClaim: %s", txClaim.Hash().StringLE())
@ -331,10 +309,7 @@ func TestCreateBasicChain(t *testing.T) {
}) })
gasOwned -= invFee gasOwned -= invFee
require.NoError(t, acc0.SignTx(txDeploy)) require.NoError(t, acc0.SignTx(txDeploy))
minerTx = nextMinerTx(validUntilBlock) b = bc.newBlock(txDeploy)
minerTx.Sender = priv0ScriptHash
require.NoError(t, acc0.SignTx(minerTx))
b = bc.newBlock(minerTx, txDeploy)
require.NoError(t, bc.AddBlock(b)) require.NoError(t, bc.AddBlock(b))
t.Logf("txDeploy: %s", txDeploy.Hash().StringLE()) t.Logf("txDeploy: %s", txDeploy.Hash().StringLE())
@ -347,10 +322,7 @@ func TestCreateBasicChain(t *testing.T) {
txInv.ValidUntilBlock = validUntilBlock txInv.ValidUntilBlock = validUntilBlock
txInv.Sender = priv0ScriptHash txInv.Sender = priv0ScriptHash
require.NoError(t, acc0.SignTx(txInv)) require.NoError(t, acc0.SignTx(txInv))
minerTx = nextMinerTx(validUntilBlock) b = bc.newBlock(txInv)
minerTx.Sender = priv0ScriptHash
require.NoError(t, acc0.SignTx(minerTx))
b = bc.newBlock(minerTx, txInv)
require.NoError(t, bc.AddBlock(b)) require.NoError(t, bc.AddBlock(b))
t.Logf("txInv: %s", txInv.Hash().StringLE()) t.Logf("txInv: %s", txInv.Hash().StringLE())
@ -376,10 +348,7 @@ func TestCreateBasicChain(t *testing.T) {
}) })
require.NoError(t, acc0.SignTx(txNeo0to1)) require.NoError(t, acc0.SignTx(txNeo0to1))
minerTx = nextMinerTx(validUntilBlock) b = bc.newBlock(txNeo0to1)
minerTx.Sender = priv0ScriptHash
require.NoError(t, acc0.SignTx(minerTx))
b = bc.newBlock(minerTx, txNeo0to1)
require.NoError(t, bc.AddBlock(b)) require.NoError(t, bc.AddBlock(b))
sh := hash.Hash160(avm) sh := hash.Hash160(avm)
@ -396,10 +365,7 @@ func TestCreateBasicChain(t *testing.T) {
transferTx.Sender = priv0ScriptHash transferTx.Sender = priv0ScriptHash
require.NoError(t, acc0.SignTx(transferTx)) require.NoError(t, acc0.SignTx(transferTx))
minerTx = nextMinerTx(validUntilBlock) b = bc.newBlock(initTx, transferTx)
minerTx.Sender = priv0ScriptHash
require.NoError(t, acc0.SignTx(minerTx))
b = bc.newBlock(minerTx, initTx, transferTx)
require.NoError(t, bc.AddBlock(b)) require.NoError(t, bc.AddBlock(b))
transferTx = newNEP5Transfer(sh, priv0.GetScriptHash(), priv1.GetScriptHash(), 123) transferTx = newNEP5Transfer(sh, priv0.GetScriptHash(), priv1.GetScriptHash(), 123)
@ -408,10 +374,7 @@ func TestCreateBasicChain(t *testing.T) {
transferTx.Sender = priv0ScriptHash transferTx.Sender = priv0ScriptHash
require.NoError(t, acc0.SignTx(transferTx)) require.NoError(t, acc0.SignTx(transferTx))
minerTx = nextMinerTx(validUntilBlock) b = bc.newBlock(transferTx)
minerTx.Sender = priv0ScriptHash
require.NoError(t, acc0.SignTx(minerTx))
b = bc.newBlock(minerTx, transferTx)
require.NoError(t, bc.AddBlock(b)) require.NoError(t, bc.AddBlock(b))
if saveChain { if saveChain {

View file

@ -48,16 +48,6 @@ func headerGetVersion(ic *interop.Context, v *vm.VM) error {
return nil return nil
} }
// headerGetConsensusData returns consensus data from the header.
func headerGetConsensusData(ic *interop.Context, v *vm.VM) error {
header, err := popHeaderFromVM(v)
if err != nil {
return err
}
v.Estack().PushVal(header.ConsensusData)
return nil
}
// headerGetMerkleRoot returns version from the header. // headerGetMerkleRoot returns version from the header.
func headerGetMerkleRoot(ic *interop.Context, v *vm.VM) error { func headerGetMerkleRoot(ic *interop.Context, v *vm.VM) error {
header, err := popHeaderFromVM(v) header, err := popHeaderFromVM(v)

View file

@ -136,16 +136,6 @@ func TestHeaderGetVersion_Negative(t *testing.T) {
require.Errorf(t, err, "value is not a header or block") require.Errorf(t, err, "value is not a header or block")
} }
func TestHeaderGetConsensusData(t *testing.T) {
v, block, context, chain := createVMAndPushBlock(t)
defer chain.Close()
err := headerGetConsensusData(context, v)
require.NoError(t, err)
value := v.Estack().Pop().Value().(*big.Int)
require.Equal(t, block.ConsensusData, value.Uint64())
}
func TestHeaderGetMerkleRoot(t *testing.T) { func TestHeaderGetMerkleRoot(t *testing.T) {
v, block, context, chain := createVMAndPushBlock(t) v, block, context, chain := createVMAndPushBlock(t)
defer chain.Close() defer chain.Close()

View file

@ -151,7 +151,6 @@ var neoInterops = []interop.Function{
{Name: "Neo.Enumerator.Create", Func: enumerator.Create, Price: 1}, {Name: "Neo.Enumerator.Create", Func: enumerator.Create, Price: 1},
{Name: "Neo.Enumerator.Next", Func: enumerator.Next, Price: 1}, {Name: "Neo.Enumerator.Next", Func: enumerator.Next, Price: 1},
{Name: "Neo.Enumerator.Value", Func: enumerator.Value, Price: 1}, {Name: "Neo.Enumerator.Value", Func: enumerator.Value, Price: 1},
{Name: "Neo.Header.GetConsensusData", Func: headerGetConsensusData, Price: 1},
{Name: "Neo.Header.GetHash", Func: headerGetHash, Price: 1}, {Name: "Neo.Header.GetHash", Func: headerGetHash, Price: 1},
{Name: "Neo.Header.GetIndex", Func: headerGetIndex, Price: 1}, {Name: "Neo.Header.GetIndex", Func: headerGetIndex, Price: 1},
{Name: "Neo.Header.GetMerkleRoot", Func: headerGetMerkleRoot, Price: 1}, {Name: "Neo.Header.GetMerkleRoot", Func: headerGetMerkleRoot, Price: 1},
@ -229,7 +228,6 @@ var neoInterops = []interop.Function{
{Name: "AntShares.Contract.GetScript", Func: contractGetScript, Price: 1}, {Name: "AntShares.Contract.GetScript", Func: contractGetScript, Price: 1},
{Name: "AntShares.Contract.GetStorageContext", Func: contractGetStorageContext, Price: 1}, {Name: "AntShares.Contract.GetStorageContext", Func: contractGetStorageContext, Price: 1},
{Name: "AntShares.Contract.Migrate", Func: contractMigrate, Price: 0}, {Name: "AntShares.Contract.Migrate", Func: contractMigrate, Price: 0},
{Name: "AntShares.Header.GetConsensusData", Func: headerGetConsensusData, Price: 1},
{Name: "AntShares.Header.GetHash", Func: headerGetHash, Price: 1}, {Name: "AntShares.Header.GetHash", Func: headerGetHash, Price: 1},
{Name: "AntShares.Header.GetMerkleRoot", Func: headerGetMerkleRoot, Price: 1}, {Name: "AntShares.Header.GetMerkleRoot", Func: headerGetMerkleRoot, Price: 1},
{Name: "AntShares.Header.GetNextConsensus", Func: headerGetNextConsensus, Price: 1}, {Name: "AntShares.Header.GetNextConsensus", Func: headerGetNextConsensus, Price: 1},

View file

@ -51,7 +51,6 @@ func TestUnexpectedNonInterops(t *testing.T) {
contractGetScript, contractGetScript,
contractGetStorageContext, contractGetStorageContext,
contractIsPayable, contractIsPayable,
headerGetConsensusData,
headerGetHash, headerGetHash,
headerGetIndex, headerGetIndex,
headerGetMerkleRoot, headerGetMerkleRoot,

View file

@ -36,7 +36,8 @@ func (fs *FeerStub) SystemFee(*transaction.Transaction) util.Fixed8 {
func testMemPoolAddRemoveWithFeer(t *testing.T, fs Feer) { func testMemPoolAddRemoveWithFeer(t *testing.T, fs Feer) {
mp := NewMemPool(10) mp := NewMemPool(10)
tx := transaction.NewMinerTXWithNonce(0) tx := transaction.NewContractTX()
tx.Nonce = 0
_, _, ok := mp.TryGetValue(tx.Hash()) _, _, ok := mp.TryGetValue(tx.Hash())
require.Equal(t, false, ok) require.Equal(t, false, ok)
require.NoError(t, mp.Add(tx, fs)) require.NoError(t, mp.Add(tx, fs))
@ -72,8 +73,8 @@ func TestMemPoolAddRemoveWithInputsAndClaims(t *testing.T) {
mpLessClaims := func(i, j int) bool { mpLessClaims := func(i, j int) bool {
return mp.claims[i].Cmp(mp.claims[j]) < 0 return mp.claims[i].Cmp(mp.claims[j]) < 0
} }
txm1 := transaction.NewContractTX()
txm1 := transaction.NewMinerTXWithNonce(1) txm1.Nonce = 1
txc1, claim1 := newClaimTX() txc1, claim1 := newClaimTX()
for i := 0; i < 5; i++ { for i := 0; i < 5; i++ {
txm1.Inputs = append(txm1.Inputs, transaction.Input{PrevHash: hash1, PrevIndex: uint16(100 - i)}) txm1.Inputs = append(txm1.Inputs, transaction.Input{PrevHash: hash1, PrevIndex: uint16(100 - i)})
@ -87,7 +88,8 @@ func TestMemPoolAddRemoveWithInputsAndClaims(t *testing.T) {
assert.Equal(t, len(claim1.Claims), len(mp.claims)) assert.Equal(t, len(claim1.Claims), len(mp.claims))
assert.True(t, sort.SliceIsSorted(mp.claims, mpLessClaims)) assert.True(t, sort.SliceIsSorted(mp.claims, mpLessClaims))
txm2 := transaction.NewMinerTXWithNonce(1) txm2 := transaction.NewContractTX()
txm2.Nonce = 1
txc2, claim2 := newClaimTX() txc2, claim2 := newClaimTX()
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
txm2.Inputs = append(txm2.Inputs, transaction.Input{PrevHash: hash2, PrevIndex: uint16(i)}) txm2.Inputs = append(txm2.Inputs, transaction.Input{PrevHash: hash2, PrevIndex: uint16(i)})
@ -128,19 +130,22 @@ func TestMemPoolAddRemoveWithInputsAndClaims(t *testing.T) {
func TestMemPoolVerifyInputs(t *testing.T) { func TestMemPoolVerifyInputs(t *testing.T) {
mp := NewMemPool(10) mp := NewMemPool(10)
tx := transaction.NewMinerTXWithNonce(1) tx := transaction.NewContractTX()
tx.Nonce = 1
inhash1 := random.Uint256() inhash1 := random.Uint256()
tx.Inputs = append(tx.Inputs, transaction.Input{PrevHash: inhash1, PrevIndex: 0}) tx.Inputs = append(tx.Inputs, transaction.Input{PrevHash: inhash1, PrevIndex: 0})
require.Equal(t, true, mp.Verify(tx)) require.Equal(t, true, mp.Verify(tx))
require.NoError(t, mp.Add(tx, &FeerStub{})) require.NoError(t, mp.Add(tx, &FeerStub{}))
tx2 := transaction.NewMinerTXWithNonce(2) tx2 := transaction.NewContractTX()
tx2.Nonce = 2
inhash2 := random.Uint256() inhash2 := random.Uint256()
tx2.Inputs = append(tx2.Inputs, transaction.Input{PrevHash: inhash2, PrevIndex: 0}) tx2.Inputs = append(tx2.Inputs, transaction.Input{PrevHash: inhash2, PrevIndex: 0})
require.Equal(t, true, mp.Verify(tx2)) require.Equal(t, true, mp.Verify(tx2))
require.NoError(t, mp.Add(tx2, &FeerStub{})) require.NoError(t, mp.Add(tx2, &FeerStub{}))
tx3 := transaction.NewMinerTXWithNonce(3) tx3 := transaction.NewContractTX()
tx3.Nonce = 3
// Different index number, but the same PrevHash as in tx1. // Different index number, but the same PrevHash as in tx1.
tx3.Inputs = append(tx3.Inputs, transaction.Input{PrevHash: inhash1, PrevIndex: 1}) tx3.Inputs = append(tx3.Inputs, transaction.Input{PrevHash: inhash1, PrevIndex: 1})
require.Equal(t, true, mp.Verify(tx3)) require.Equal(t, true, mp.Verify(tx3))
@ -211,7 +216,8 @@ func TestOverCapacity(t *testing.T) {
mp := NewMemPool(mempoolSize) mp := NewMemPool(mempoolSize)
for i := 0; i < mempoolSize; i++ { for i := 0; i < mempoolSize; i++ {
tx := transaction.NewMinerTXWithNonce(uint32(i)) tx := transaction.NewContractTX()
tx.Nonce = uint32(i)
require.NoError(t, mp.Add(tx, fs)) require.NoError(t, mp.Add(tx, fs))
} }
txcnt := uint32(mempoolSize) txcnt := uint32(mempoolSize)
@ -231,7 +237,8 @@ func TestOverCapacity(t *testing.T) {
// Fees are also prioritized. // Fees are also prioritized.
fs.netFee = util.Fixed8FromFloat(0.0001) fs.netFee = util.Fixed8FromFloat(0.0001)
for i := 0; i < mempoolSize-1; i++ { for i := 0; i < mempoolSize-1; i++ {
tx := transaction.NewMinerTXWithNonce(txcnt) tx := transaction.NewContractTX()
tx.Nonce = txcnt
txcnt++ txcnt++
require.NoError(t, mp.Add(tx, fs)) require.NoError(t, mp.Add(tx, fs))
require.Equal(t, mempoolSize, mp.Count()) require.Equal(t, mempoolSize, mp.Count())
@ -239,7 +246,8 @@ func TestOverCapacity(t *testing.T) {
} }
// Less prioritized txes are not allowed anymore. // Less prioritized txes are not allowed anymore.
fs.netFee = util.Fixed8FromFloat(0.00001) fs.netFee = util.Fixed8FromFloat(0.00001)
tx := transaction.NewMinerTXWithNonce(txcnt) tx := transaction.NewContractTX()
tx.Nonce = txcnt
txcnt++ txcnt++
require.Error(t, mp.Add(tx, fs)) require.Error(t, mp.Add(tx, fs))
require.Equal(t, mempoolSize, mp.Count()) require.Equal(t, mempoolSize, mp.Count())
@ -250,7 +258,8 @@ func TestOverCapacity(t *testing.T) {
// Low net fee, but higher per-byte fee is still a better combination. // Low net fee, but higher per-byte fee is still a better combination.
fs.perByteFee = util.Fixed8FromFloat(0.001) fs.perByteFee = util.Fixed8FromFloat(0.001)
tx = transaction.NewMinerTXWithNonce(txcnt) tx = transaction.NewContractTX()
tx.Nonce = txcnt
txcnt++ txcnt++
require.NoError(t, mp.Add(tx, fs)) require.NoError(t, mp.Add(tx, fs))
require.Equal(t, mempoolSize, mp.Count()) require.Equal(t, mempoolSize, mp.Count())
@ -259,7 +268,8 @@ func TestOverCapacity(t *testing.T) {
// High priority always wins over low priority. // High priority always wins over low priority.
fs.lowPriority = false fs.lowPriority = false
for i := 0; i < mempoolSize; i++ { for i := 0; i < mempoolSize; i++ {
tx := transaction.NewMinerTXWithNonce(txcnt) tx := transaction.NewContractTX()
tx.Nonce = txcnt
txcnt++ txcnt++
require.NoError(t, mp.Add(tx, fs)) require.NoError(t, mp.Add(tx, fs))
require.Equal(t, mempoolSize, mp.Count()) require.Equal(t, mempoolSize, mp.Count())
@ -267,7 +277,8 @@ func TestOverCapacity(t *testing.T) {
} }
// Good luck with low priority now. // Good luck with low priority now.
fs.lowPriority = true fs.lowPriority = true
tx = transaction.NewMinerTXWithNonce(txcnt) tx = transaction.NewContractTX()
tx.Nonce = txcnt
require.Error(t, mp.Add(tx, fs)) require.Error(t, mp.Add(tx, fs))
require.Equal(t, mempoolSize, mp.Count()) require.Equal(t, mempoolSize, mp.Count())
require.Equal(t, true, sort.IsSorted(sort.Reverse(mp.verifiedTxes))) require.Equal(t, true, sort.IsSorted(sort.Reverse(mp.verifiedTxes)))
@ -280,7 +291,8 @@ func TestGetVerified(t *testing.T) {
txes := make([]*transaction.Transaction, 0, mempoolSize) txes := make([]*transaction.Transaction, 0, mempoolSize)
for i := 0; i < mempoolSize; i++ { for i := 0; i < mempoolSize; i++ {
tx := transaction.NewMinerTXWithNonce(uint32(i)) tx := transaction.NewContractTX()
tx.Nonce = uint32(i)
txes = append(txes, tx) txes = append(txes, tx)
require.NoError(t, mp.Add(tx, fs)) require.NoError(t, mp.Add(tx, fs))
} }
@ -305,7 +317,8 @@ func TestRemoveStale(t *testing.T) {
txes1 := make([]*transaction.Transaction, 0, mempoolSize/2) txes1 := make([]*transaction.Transaction, 0, mempoolSize/2)
txes2 := make([]*transaction.Transaction, 0, mempoolSize/2) txes2 := make([]*transaction.Transaction, 0, mempoolSize/2)
for i := 0; i < mempoolSize; i++ { for i := 0; i < mempoolSize; i++ {
tx := transaction.NewMinerTXWithNonce(uint32(i)) tx := transaction.NewContractTX()
tx.Nonce = uint32(i)
if i%2 == 0 { if i%2 == 0 {
txes1 = append(txes1, tx) txes1 = append(txes1, tx)
} else { } else {

View file

@ -2,7 +2,6 @@ package core
import ( import (
"errors" "errors"
"math/rand"
"testing" "testing"
"github.com/nspcc-dev/neo-go/pkg/core/interop" "github.com/nspcc-dev/neo-go/pkg/core/interop"
@ -90,13 +89,11 @@ func TestNativeContract_Invoke(t *testing.T) {
emit.AppCallWithOperationAndArgs(w.BinWriter, tn.Metadata().Hash, "sum", int64(14), int64(28)) emit.AppCallWithOperationAndArgs(w.BinWriter, tn.Metadata().Hash, "sum", int64(14), int64(28))
script := w.Bytes() script := w.Bytes()
tx := transaction.NewInvocationTX(script, 0) tx := transaction.NewInvocationTX(script, 0)
mn := transaction.NewMinerTXWithNonce(rand.Uint32())
validUntil := chain.blockHeight + 1 validUntil := chain.blockHeight + 1
tx.ValidUntilBlock = validUntil tx.ValidUntilBlock = validUntil
mn.ValidUntilBlock = validUntil require.NoError(t, addSender(tx))
require.NoError(t, addSender(tx, mn)) require.NoError(t, signTx(chain, tx))
require.NoError(t, signTx(chain, tx, mn)) b := chain.newBlock(tx)
b := chain.newBlock(mn, tx)
require.NoError(t, chain.AddBlock(b)) require.NoError(t, chain.AddBlock(b))
res, err := chain.GetAppExecResult(tx.Hash()) res, err := chain.GetAppExecResult(tx.Hash())

View file

@ -20,7 +20,7 @@ type NEP5TransferLog struct {
} }
// NEP5TransferSize is a size of a marshaled NEP5Transfer struct in bytes. // NEP5TransferSize is a size of a marshaled NEP5Transfer struct in bytes.
const NEP5TransferSize = util.Uint160Size*3 + 8 + 4 + 4 + util.Uint256Size const NEP5TransferSize = util.Uint160Size*3 + 8 + 4 + 8 + util.Uint256Size
// NEP5Transfer represents a single NEP5 Transfer event. // NEP5Transfer represents a single NEP5 Transfer event.
type NEP5Transfer struct { type NEP5Transfer struct {
@ -36,7 +36,7 @@ type NEP5Transfer struct {
// Block is a number of block when the event occured. // Block is a number of block when the event occured.
Block uint32 Block uint32
// Timestamp is the timestamp of the block where transfer occured. // Timestamp is the timestamp of the block where transfer occured.
Timestamp uint32 Timestamp uint64
// Tx is a hash the transaction. // Tx is a hash the transaction.
Tx util.Uint256 Tx util.Uint256
} }
@ -135,7 +135,7 @@ func (t *NEP5Transfer) EncodeBinary(w *io.BinWriter) {
w.WriteBytes(t.From[:]) w.WriteBytes(t.From[:])
w.WriteBytes(t.To[:]) w.WriteBytes(t.To[:])
w.WriteU32LE(t.Block) w.WriteU32LE(t.Block)
w.WriteU32LE(t.Timestamp) w.WriteU64LE(t.Timestamp)
w.WriteU64LE(uint64(t.Amount)) w.WriteU64LE(uint64(t.Amount))
} }
@ -146,6 +146,6 @@ func (t *NEP5Transfer) DecodeBinary(r *io.BinReader) {
r.ReadBytes(t.From[:]) r.ReadBytes(t.From[:])
r.ReadBytes(t.To[:]) r.ReadBytes(t.To[:])
t.Block = r.ReadU32LE() t.Block = r.ReadU32LE()
t.Timestamp = r.ReadU32LE() t.Timestamp = r.ReadU64LE()
t.Amount = int64(r.ReadU64LE()) t.Amount = int64(r.ReadU64LE())
} }

View file

@ -1,38 +0,0 @@
package transaction
import (
"math/rand"
"github.com/nspcc-dev/neo-go/pkg/io"
)
// MinerTX represents a miner transaction.
type MinerTX struct{}
// NewMinerTX creates Transaction of MinerType type.
func NewMinerTX() *Transaction {
return NewMinerTXWithNonce(rand.Uint32())
}
// NewMinerTXWithNonce creates Transaction of MinerType type with specified nonce.
func NewMinerTXWithNonce(nonce uint32) *Transaction {
return &Transaction{
Type: MinerType,
Version: 0,
Nonce: nonce,
Data: &MinerTX{},
Attributes: []Attribute{},
Inputs: []Input{},
Outputs: []Output{},
Scripts: []Witness{},
Trimmed: false,
}
}
// DecodeBinary implements Serializable interface.
func (tx *MinerTX) DecodeBinary(r *io.BinReader) {
}
// EncodeBinary implements Serializable interface.
func (tx *MinerTX) EncodeBinary(w *io.BinWriter) {
}

View file

@ -1,21 +0,0 @@
package transaction
// TODO NEO3.0: Update binary
/*
func TestEncodeDecodeMiner(t *testing.T) {
// transaction from mainnet a1f219dc6be4c35eca172e65e02d4591045220221b1543f1a4b67b9e9442c264
rawtx := "0000fcd30e22000001e72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c60c8000000000000001f72e68b4e39602912106d53b229378a082784b200"
tx := decodeTransaction(rawtx, t)
assert.Equal(t, MinerType, tx.Type)
assert.IsType(t, tx.Data, &MinerTX{})
assert.Equal(t, 0, int(tx.Version))
assert.Equal(t, uint32(571397116), tx.Nonce)
assert.Equal(t, "a1f219dc6be4c35eca172e65e02d4591045220221b1543f1a4b67b9e9442c264", tx.Hash().StringLE())
// Encode
data, err := testserdes.EncodeBinary(tx)
assert.NoError(t, err)
assert.Equal(t, rawtx, hex.EncodeToString(data))
}
*/

View file

@ -148,9 +148,6 @@ func (t *Transaction) decodeData(r *io.BinReader) {
case InvocationType: case InvocationType:
t.Data = &InvocationTX{Version: t.Version} t.Data = &InvocationTX{Version: t.Version}
t.Data.(*InvocationTX).DecodeBinary(r) t.Data.(*InvocationTX).DecodeBinary(r)
case MinerType:
t.Data = &MinerTX{}
t.Data.(*MinerTX).DecodeBinary(r)
case ClaimType: case ClaimType:
t.Data = &ClaimTX{} t.Data = &ClaimTX{}
t.Data.(*ClaimTX).DecodeBinary(r) t.Data.(*ClaimTX).DecodeBinary(r)
@ -335,8 +332,6 @@ func (t *Transaction) UnmarshalJSON(data []byte) error {
} }
t.Sender = sender t.Sender = sender
switch tx.Type { switch tx.Type {
case MinerType:
t.Data = &MinerTX{}
case ClaimType: case ClaimType:
t.Data = &ClaimTX{ t.Data = &ClaimTX{
Claims: tx.Claims, Claims: tx.Claims,

View file

@ -120,12 +120,6 @@ func TestMarshalUnmarshalJSONContractTX(t *testing.T) {
testserdes.MarshalUnmarshalJSON(t, tx, new(Transaction)) testserdes.MarshalUnmarshalJSON(t, tx, new(Transaction))
} }
func TestMarshalUnmarshalJSONMinerTX(t *testing.T) {
tx := NewMinerTX()
testserdes.MarshalUnmarshalJSON(t, tx, new(Transaction))
}
func TestMarshalUnmarshalJSONClaimTX(t *testing.T) { func TestMarshalUnmarshalJSONClaimTX(t *testing.T) {
tx := &Transaction{ tx := &Transaction{
Type: ClaimType, Type: ClaimType,

View file

@ -11,7 +11,6 @@ type TXType uint8
// Constants for all valid transaction types. // Constants for all valid transaction types.
const ( const (
MinerType TXType = 0x00
IssueType TXType = 0x01 IssueType TXType = 0x01
ClaimType TXType = 0x02 ClaimType TXType = 0x02
RegisterType TXType = 0x40 RegisterType TXType = 0x40
@ -22,8 +21,6 @@ const (
// String implements the stringer interface. // String implements the stringer interface.
func (t TXType) String() string { func (t TXType) String() string {
switch t { switch t {
case MinerType:
return "MinerTransaction"
case IssueType: case IssueType:
return "IssueTransaction" return "IssueTransaction"
case ClaimType: case ClaimType:
@ -58,8 +55,6 @@ func (t *TXType) UnmarshalJSON(data []byte) error {
// TXTypeFromString searches for TXType by string name. // TXTypeFromString searches for TXType by string name.
func TXTypeFromString(jsonString string) (TXType, error) { func TXTypeFromString(jsonString string) (TXType, error) {
switch jsonString = strings.TrimSpace(jsonString); jsonString { switch jsonString = strings.TrimSpace(jsonString); jsonString {
case "MinerTransaction":
return MinerType, nil
case "IssueTransaction": case "IssueTransaction":
return IssueType, nil return IssueType, nil
case "ClaimTransaction": case "ClaimTransaction":

View file

@ -41,9 +41,8 @@ func createGenesisBlock(cfg config.ProtocolConfiguration) (*block.Block, error)
base := block.Base{ base := block.Base{
Version: 0, Version: 0,
PrevHash: util.Uint256{}, PrevHash: util.Uint256{},
Timestamp: uint32(time.Date(2016, 7, 15, 15, 8, 21, 0, time.UTC).Unix()), Timestamp: uint64(time.Date(2016, 7, 15, 15, 8, 21, 0, time.UTC).Unix()),
Index: 0, Index: 0,
ConsensusData: 2083236893,
NextConsensus: nextConsensus, NextConsensus: nextConsensus,
Script: transaction.Witness{ Script: transaction.Witness{
InvocationScript: []byte{}, InvocationScript: []byte{},
@ -60,9 +59,6 @@ func createGenesisBlock(cfg config.ProtocolConfiguration) (*block.Block, error)
} }
scriptOut := hash.Hash160(rawScript) scriptOut := hash.Hash160(rawScript)
minerTx := transaction.NewMinerTXWithNonce(2083236893)
minerTx.Sender = hash.Hash160([]byte{byte(opcode.PUSH1)})
issueTx := transaction.NewIssueTX() issueTx := transaction.NewIssueTX()
// TODO NEO3.0: nonce should be constant to avoid variability of genesis block // TODO NEO3.0: nonce should be constant to avoid variability of genesis block
issueTx.Nonce = 0 issueTx.Nonce = 0
@ -84,12 +80,15 @@ func createGenesisBlock(cfg config.ProtocolConfiguration) (*block.Block, error)
b := &block.Block{ b := &block.Block{
Base: base, Base: base,
Transactions: []*transaction.Transaction{ Transactions: []*transaction.Transaction{
minerTx,
&governingTokenTX, &governingTokenTX,
&utilityTokenTX, &utilityTokenTX,
issueTx, issueTx,
deployNativeContracts(), deployNativeContracts(),
}, },
ConsensusData: block.ConsensusData{
PrimaryIndex: 0,
Nonce: 2083236893,
},
} }
if err = b.RebuildMerkleRoot(); err != nil { if err = b.RebuildMerkleRoot(); err != nil {

View file

@ -20,7 +20,7 @@ func TestGenesisBlockMainNet(t *testing.T) {
// have been changed. Consequently, hash of the genesis block has been changed. // have been changed. Consequently, hash of the genesis block has been changed.
// Update expected genesis block hash for better times. // Update expected genesis block hash for better times.
// Old hash is "d42561e3d30e15be6400b6df2f328e02d2bf6354c41dce433bc57687c82144bf" // Old hash is "d42561e3d30e15be6400b6df2f328e02d2bf6354c41dce433bc57687c82144bf"
expect := "094c2c2db5dcb868d85aa4d652aed23bc67e7166f53223a228e382265b1be84b" expect := "16ffda4cc6a9b0a0ca63f1571f7724418c43f014e2eb4e8614b4938ccf0f20f6"
assert.Equal(t, expect, block.Hash().StringLE()) assert.Equal(t, expect, block.Hash().StringLE())
} }

View file

@ -1,7 +1,6 @@
package payload package payload
import ( import (
"encoding/hex"
"testing" "testing"
"github.com/nspcc-dev/neo-go/pkg/core/block" "github.com/nspcc-dev/neo-go/pkg/core/block"
@ -65,6 +64,8 @@ func testHeadersEncodeDecode(t *testing.T, headers *Headers, expected int, limit
} }
} }
//TODO NEO3.0: Update binary
/*
func TestBinEncodeDecode(t *testing.T) { func TestBinEncodeDecode(t *testing.T) {
rawBlockHeaders := "010000000026b3c3df4dc1602a3b0e6989248b23275b5e4014a159af5dce69e16d4ab75f00f439321a51f425a530820cfe4d715bfd835b49687e87772f2c4737b8bc586dca7fda03580a000000bf14ff160228f0c059e75d652b5d3827bf04c165bbe9ef95cca4bf5501fd45014036fdd23248880c1c311bcd97df04fe6d740dc1bf340c26915f0466e31e81c039012eca7a760270389e04b58b99820fe49cf8c24c9afc65d696b4d3f406a1e6b5405172a9b461e68dd399c8716de11d31f7dd2ec3be327c636b024562db6ac5df1cffdbee74c994736fd49803234d2baffbc0054f28ba5ec76494a467b4106955bb4084af7746d269241628c667003e9d39288b190ad5cef218ada625cbba8be411bb153828d8d3634e8f586638e2448425bc5b671be69800392ccbdebc945a5099c7406f6a11824105ecad345e525957053e77fbc0119d6b3fa7f854527e816cfce0d95dac66888e07e8990c95103d8e46124aac16f152e088520d7ec8325e3a2456f840e5b77ef0e3c410b347ccaf8a87516d10b88d436563c80712153273993afc320ec49b638225f58de464a1345e62a564b398939f96f6f4b7cf21b583609f85495af1552102486fd15702c4490a26703112a5cc1d0923fd697a33406bd5a1c00e0013b09a7021024c7b7fb6c310fccf1ba33b082519d82964ea93868d676662d4a59ad548df0e7d2102aaec38470f6aad0042c6e877cfd8087d2676b0f516fddd362801b9bd3936399e2103b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c2103b8d9d5771d8f513aa0869b9cc8d50986403b78c6da36890638c3d46a5adce04a2102ca0e27697b9c248f6f16e085fd0061e26f44da85b58ee835c110caa5ec3ba5542102df48f60e8f3e01c48ff40b9b7f1310d7a8b2a193188befe1c2e3df740e89509357ae00" rawBlockHeaders := "010000000026b3c3df4dc1602a3b0e6989248b23275b5e4014a159af5dce69e16d4ab75f00f439321a51f425a530820cfe4d715bfd835b49687e87772f2c4737b8bc586dca7fda03580a000000bf14ff160228f0c059e75d652b5d3827bf04c165bbe9ef95cca4bf5501fd45014036fdd23248880c1c311bcd97df04fe6d740dc1bf340c26915f0466e31e81c039012eca7a760270389e04b58b99820fe49cf8c24c9afc65d696b4d3f406a1e6b5405172a9b461e68dd399c8716de11d31f7dd2ec3be327c636b024562db6ac5df1cffdbee74c994736fd49803234d2baffbc0054f28ba5ec76494a467b4106955bb4084af7746d269241628c667003e9d39288b190ad5cef218ada625cbba8be411bb153828d8d3634e8f586638e2448425bc5b671be69800392ccbdebc945a5099c7406f6a11824105ecad345e525957053e77fbc0119d6b3fa7f854527e816cfce0d95dac66888e07e8990c95103d8e46124aac16f152e088520d7ec8325e3a2456f840e5b77ef0e3c410b347ccaf8a87516d10b88d436563c80712153273993afc320ec49b638225f58de464a1345e62a564b398939f96f6f4b7cf21b583609f85495af1552102486fd15702c4490a26703112a5cc1d0923fd697a33406bd5a1c00e0013b09a7021024c7b7fb6c310fccf1ba33b082519d82964ea93868d676662d4a59ad548df0e7d2102aaec38470f6aad0042c6e877cfd8087d2676b0f516fddd362801b9bd3936399e2103b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c2103b8d9d5771d8f513aa0869b9cc8d50986403b78c6da36890638c3d46a5adce04a2102ca0e27697b9c248f6f16e085fd0061e26f44da85b58ee835c110caa5ec3ba5542102df48f60e8f3e01c48ff40b9b7f1310d7a8b2a193188befe1c2e3df740e89509357ae00"
@ -84,3 +85,4 @@ func TestBinEncodeDecode(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, hex.EncodeToString(rawBlockBytes), hex.EncodeToString(data)) assert.Equal(t, hex.EncodeToString(rawBlockBytes), hex.EncodeToString(data))
} }
*/

View file

@ -803,9 +803,6 @@ func (s *Server) relayBlock(b *block.Block) {
// verifyAndPoolTX verifies the TX and adds it to the local mempool. // verifyAndPoolTX verifies the TX and adds it to the local mempool.
func (s *Server) verifyAndPoolTX(t *transaction.Transaction) RelayReason { func (s *Server) verifyAndPoolTX(t *transaction.Transaction) RelayReason {
if t.Type == transaction.MinerType {
return RelayInvalid
}
if err := s.chain.PoolTx(t); err != nil { if err := s.chain.PoolTx(t); err != nil {
switch err { switch err {
case core.ErrAlreadyExists: case core.ErrAlreadyExists:

View file

@ -136,17 +136,17 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
invoke: func(c *Client) (interface{}, error) { invoke: func(c *Client) (interface{}, error) {
return c.GetBlockByIndex(5) return c.GetBlockByIndex(5)
}, },
serverResponse: `{"id":1,"jsonrpc":"2.0","result":"00000000b3aa04926a237abc2e54808fb10b5ca2394ae5ccfff17d60c1e393cfd418ed8f265f271088384b2f696e34bea0c8e02cf226351800c0866c1586be521536e579997c9d5e050000005704000000000000be48d3a3f5d10013ab9ffee489706078714f1ea201fd040140a6cc2c7fdee4f8fd97f84114d04edda16a37a4c088da9d5be3233e118fccdf73c0305d2cbd15ea0dbcedb594fec3044844e8f59f236ded7fccb1eda2eee2c76740197eba5d648d650ca1d73b8c0a0c7cdc22d31d7b2564764729d271e7ff6378c4f2228f657d65fec530f2af6cdc7af3bc2ab17a7b8175376601fb17ec951faf074038222bb0430f7808d333be3fb8e5b93c490dbb07e6c085350ba64cb7de61127067d1825de30915964dbb345f3b902d61dbf9a294c11ff6459000648f0dc4e66740926854a25b9ea87d7fffe0253bf2bcb3d153434cc0a8ba166136d16aef9a3de70ba3704ba3103a26d01c2bdbeb7262a19bbceab6a7487beba5e55f7ee768a0808b532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae010000d5040000be48d3a3f5d10013ab9ffee489706078714f1ea20500000000000001fd040140f50121bb6ec9d8e0d1c15eea66b2ff7b51bb1bc4b3da27d9eac1d46b59e6a319bb1db4eb710c7f1931b0c2deaa2389a0fc3fe8c761cec40906b7973450c43173402dc082417a6815e722216de0b857eda6c846bf435088d543d2ab89f1dd92488e87b4d2c6508b0db945cbe6968e85c1c6d57274bfc898e82876c5cb08613da5d64053100f0162a41709a37305c300e7d6ac0d46575aab98dade7375b8d9ca980086594f1288dc68da0e0e42913d1c68024f63442a79c9478971d3ad93c5467ec53040a1c3a772a88b09cba8cc8ec3b46c0c0db6ac86519a7fd7db29b43d34e804a22d8839eaeb35e2a1e05d591fbad4ae290b90c6dc02dddbe28b2b3bf0fec2a337dd8b532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae"}`, serverResponse: `{"id":1,"jsonrpc":"2.0","result":"000000005b25cf560918b13cc7a10071cf616426a103d58498171567aaa116af69179aa3c05c359ade4316392d69d5ca01f8860f8bdebbe1a8f752edd68d9a6a2d204fe752cca25e0000000005000000e903736ceceeceae1806eee0e3ec61e7cce476ce01fd08010c407f70912fdcd0ce9a70963110eb39ef73ed02512ea63bc1c55577474df8f364a874999b16666888f8a3ca69873054a31ab42dd1fee1ed8605ff65edb39797e34e0c40d59459cb1cc8270d9a813aa444852a5d7714aed0b25373ec07549349c6db32b6c8c2e43cdd7b1ad2a4154cb5ff1222d9d7010877016a59775abdd2c08f253c850c4048b65cb58e0d58f2dd0f5db3b195c5784933d6179d8317217ba46f9deac9a667bffb1afd0dd86bdae6267af4c2605f7401849a0b980fcecfeae95df7f5ca6e140c406d9b1942c5aa80070ad484b3dd76421a3f46327670bea94e3ecb3a94eef8843a75195b55872a7c503acb01ab368cdaa11a9e5fb80d55bbd6b861233ba84edcf894130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b683073b3bb020057040000000000008000d5040000e903736ceceeceae1806eee0e3ec61e7cce476ce0500000000000001fd08010c40ae62dadb95b21628921adb9ee14e8c1f20d68b9d6ffba218f8e403af70126449435a53525cd6f1d1c871e64a91025866cd8a413ec70e3cde0ddf62931aa22baa0c40c3e09fc8ad46789d645240634ef40bd180e0dba75beae07a37dc2e899b68b4b3b3a67d076ea9444ed143dbb3264702914a4662ff95859d32c9b5bb5bdc9ec1d60c40b2511115482bd860d85f57103fb8cce2cb45ba8461d4e164685b426cb5df1525e6f09dd7aa23db0fec2241bde7c925e22f3cba3824ea461455515dc2a1455f5e0c40c0aee2528e7fd75a0434f4d67da58507e8d349ca29e01e7eafa9f283e8b8c05d06587db7234f111730c14c8a4bfb7a1ffd9493b9696c71e68966c6bf4a832ab794130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b683073b3bb"}`,
result: func(c *Client) interface{} { return &block.Block{} }, result: func(c *Client) interface{} { return &block.Block{} },
check: func(t *testing.T, c *Client, result interface{}) { check: func(t *testing.T, c *Client, result interface{}) {
res, ok := result.(*block.Block) res, ok := result.(*block.Block)
require.True(t, ok) require.True(t, ok)
assert.Equal(t, uint32(0), res.Version) assert.Equal(t, uint32(0), res.Version)
assert.Equal(t, "66d1c140fbdc0eaa47e69a6a9c5034ebc3a449db98da565191ab863d1a079906", res.Hash().StringLE()) assert.Equal(t, "81b74dcfc3a42ef331eec2486231aba300ec9a95b024b0151214c76305d409bb", res.Hash().StringLE())
assert.Equal(t, "8fed18d4cf93e3c1607df1ffcce54a39a25c0bb18f80542ebc7a236a9204aab3", res.PrevHash.StringLE()) assert.Equal(t, "a39a1769af16a1aa6715179884d503a1266461cf7100a1c73cb1180956cf255b", res.PrevHash.StringLE())
assert.Equal(t, "79e5361552be86156c86c000183526f22ce0c8a0be346e692f4b388810275f26", res.MerkleRoot.StringLE()) assert.Equal(t, "e74f202d6a9a8dd6ed52f7a8e1bbde8b0f86f801cad5692d391643de9a355cc0", res.MerkleRoot.StringLE())
assert.Equal(t, 1, len(res.Transactions)) assert.Equal(t, 1, len(res.Transactions))
assert.Equal(t, "79e5361552be86156c86c000183526f22ce0c8a0be346e692f4b388810275f26", res.Transactions[0].Hash().StringLE()) assert.Equal(t, "69d95138263dc54c07826ef1d76f9eb32ff6bf7fc3fc3281194b46ec7683ceb3", res.Transactions[0].Hash().StringLE())
}, },
}, },
{ {
@ -154,45 +154,46 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
invoke: func(c *Client) (i interface{}, err error) { invoke: func(c *Client) (i interface{}, err error) {
return c.GetBlockByIndexVerbose(5) return c.GetBlockByIndexVerbose(5)
}, },
serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"hash":"0x66d1c140fbdc0eaa47e69a6a9c5034ebc3a449db98da565191ab863d1a079906","size":946,"version":0,"nextblockhash":"0xf6749a5eb21273ec67951afd22282f002e605e210678c2fa765dbecf0124bd1a","previousblockhash":"0x8fed18d4cf93e3c1607df1ffcce54a39a25c0bb18f80542ebc7a236a9204aab3","merkleroot":"0x79e5361552be86156c86c000183526f22ce0c8a0be346e692f4b388810275f26","time":1587379353,"index":5,"nonce":"0000000000000457","nextconsensus":"AZ81H31DMWzbSnFDLFkzh9vHwaDLayV7fU","confirmations":203,"script":{"invocation":"40a6cc2c7fdee4f8fd97f84114d04edda16a37a4c088da9d5be3233e118fccdf73c0305d2cbd15ea0dbcedb594fec3044844e8f59f236ded7fccb1eda2eee2c76740197eba5d648d650ca1d73b8c0a0c7cdc22d31d7b2564764729d271e7ff6378c4f2228f657d65fec530f2af6cdc7af3bc2ab17a7b8175376601fb17ec951faf074038222bb0430f7808d333be3fb8e5b93c490dbb07e6c085350ba64cb7de61127067d1825de30915964dbb345f3b902d61dbf9a294c11ff6459000648f0dc4e66740926854a25b9ea87d7fffe0253bf2bcb3d153434cc0a8ba166136d16aef9a3de70ba3704ba3103a26d01c2bdbeb7262a19bbceab6a7487beba5e55f7ee768a080","verification":"532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae"},"tx":[{"sys_fee":"0","net_fee":"0","txid":"0x79e5361552be86156c86c000183526f22ce0c8a0be346e692f4b388810275f26","size":437,"type":"MinerTransaction","version":0,"nonce":1237,"sender":"AZ81H31DMWzbSnFDLFkzh9vHwaDLayV7fU","valid_until_block":5,"attributes":[],"vin":[],"vout":[],"scripts":[{"invocation":"40f50121bb6ec9d8e0d1c15eea66b2ff7b51bb1bc4b3da27d9eac1d46b59e6a319bb1db4eb710c7f1931b0c2deaa2389a0fc3fe8c761cec40906b7973450c43173402dc082417a6815e722216de0b857eda6c846bf435088d543d2ab89f1dd92488e87b4d2c6508b0db945cbe6968e85c1c6d57274bfc898e82876c5cb08613da5d64053100f0162a41709a37305c300e7d6ac0d46575aab98dade7375b8d9ca980086594f1288dc68da0e0e42913d1c68024f63442a79c9478971d3ad93c5467ec53040a1c3a772a88b09cba8cc8ec3b46c0c0db6ac86519a7fd7db29b43d34e804a22d8839eaeb35e2a1e05d591fbad4ae290b90c6dc02dddbe28b2b3bf0fec2a337dd","verification":"532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae"}]}]}}`, serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"hash":"0x81b74dcfc3a42ef331eec2486231aba300ec9a95b024b0151214c76305d409bb","size":977,"version":0,"nextblockhash":"0xd08e408909ae24de3470a3f231f966e15719910cb7b1a30f356b3e784c1ddf6a","previousblockhash":"0xa39a1769af16a1aa6715179884d503a1266461cf7100a1c73cb1180956cf255b","merkleroot":"0xe74f202d6a9a8dd6ed52f7a8e1bbde8b0f86f801cad5692d391643de9a355cc0","time":1587727442,"index":5,"consensus_data":{"primary":0,"nonce":"0000000000000457"},"nextconsensus":"Ad1wDxzcRiRSryvJobNV211Tv7UUiziPXy","confirmations":203,"script":{"invocation":"0c407f70912fdcd0ce9a70963110eb39ef73ed02512ea63bc1c55577474df8f364a874999b16666888f8a3ca69873054a31ab42dd1fee1ed8605ff65edb39797e34e0c40d59459cb1cc8270d9a813aa444852a5d7714aed0b25373ec07549349c6db32b6c8c2e43cdd7b1ad2a4154cb5ff1222d9d7010877016a59775abdd2c08f253c850c4048b65cb58e0d58f2dd0f5db3b195c5784933d6179d8317217ba46f9deac9a667bffb1afd0dd86bdae6267af4c2605f7401849a0b980fcecfeae95df7f5ca6e140c406d9b1942c5aa80070ad484b3dd76421a3f46327670bea94e3ecb3a94eef8843a75195b55872a7c503acb01ab368cdaa11a9e5fb80d55bbd6b861233ba84edcf8","verification":"130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b683073b3bb"},"tx":[{"sys_fee":"0","net_fee":"0","txid":"0x69d95138263dc54c07826ef1d76f9eb32ff6bf7fc3fc3281194b46ec7683ceb3","size":450,"type":"ContractTransaction","version":0,"nonce":1237,"sender":"Ad1wDxzcRiRSryvJobNV211Tv7UUiziPXy","valid_until_block":5,"attributes":[],"vin":[],"vout":[],"scripts":[{"invocation":"0c40ae62dadb95b21628921adb9ee14e8c1f20d68b9d6ffba218f8e403af70126449435a53525cd6f1d1c871e64a91025866cd8a413ec70e3cde0ddf62931aa22baa0c40c3e09fc8ad46789d645240634ef40bd180e0dba75beae07a37dc2e899b68b4b3b3a67d076ea9444ed143dbb3264702914a4662ff95859d32c9b5bb5bdc9ec1d60c40b2511115482bd860d85f57103fb8cce2cb45ba8461d4e164685b426cb5df1525e6f09dd7aa23db0fec2241bde7c925e22f3cba3824ea461455515dc2a1455f5e0c40c0aee2528e7fd75a0434f4d67da58507e8d349ca29e01e7eafa9f283e8b8c05d06587db7234f111730c14c8a4bfb7a1ffd9493b9696c71e68966c6bf4a832ab7","verification":"130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b683073b3bb"}]}]}}`,
result: func(c *Client) interface{} { result: func(c *Client) interface{} {
hash, err := util.Uint256DecodeStringLE("66d1c140fbdc0eaa47e69a6a9c5034ebc3a449db98da565191ab863d1a079906") hash, err := util.Uint256DecodeStringLE("81b74dcfc3a42ef331eec2486231aba300ec9a95b024b0151214c76305d409bb")
if err != nil { if err != nil {
panic(err) panic(err)
} }
nextBlockHash, err := util.Uint256DecodeStringLE("f6749a5eb21273ec67951afd22282f002e605e210678c2fa765dbecf0124bd1a") nextBlockHash, err := util.Uint256DecodeStringLE("d08e408909ae24de3470a3f231f966e15719910cb7b1a30f356b3e784c1ddf6a")
if err != nil { if err != nil {
panic(err) panic(err)
} }
prevBlockHash, err := util.Uint256DecodeStringLE("8fed18d4cf93e3c1607df1ffcce54a39a25c0bb18f80542ebc7a236a9204aab3") prevBlockHash, err := util.Uint256DecodeStringLE("a39a1769af16a1aa6715179884d503a1266461cf7100a1c73cb1180956cf255b")
if err != nil { if err != nil {
panic(err) panic(err)
} }
merkleRoot, err := util.Uint256DecodeStringLE("79e5361552be86156c86c000183526f22ce0c8a0be346e692f4b388810275f26") merkleRoot, err := util.Uint256DecodeStringLE("e74f202d6a9a8dd6ed52f7a8e1bbde8b0f86f801cad5692d391643de9a355cc0")
if err != nil { if err != nil {
panic(err) panic(err)
} }
invScript, err := hex.DecodeString("40a6cc2c7fdee4f8fd97f84114d04edda16a37a4c088da9d5be3233e118fccdf73c0305d2cbd15ea0dbcedb594fec3044844e8f59f236ded7fccb1eda2eee2c76740197eba5d648d650ca1d73b8c0a0c7cdc22d31d7b2564764729d271e7ff6378c4f2228f657d65fec530f2af6cdc7af3bc2ab17a7b8175376601fb17ec951faf074038222bb0430f7808d333be3fb8e5b93c490dbb07e6c085350ba64cb7de61127067d1825de30915964dbb345f3b902d61dbf9a294c11ff6459000648f0dc4e66740926854a25b9ea87d7fffe0253bf2bcb3d153434cc0a8ba166136d16aef9a3de70ba3704ba3103a26d01c2bdbeb7262a19bbceab6a7487beba5e55f7ee768a080") invScript, err := hex.DecodeString("0c407f70912fdcd0ce9a70963110eb39ef73ed02512ea63bc1c55577474df8f364a874999b16666888f8a3ca69873054a31ab42dd1fee1ed8605ff65edb39797e34e0c40d59459cb1cc8270d9a813aa444852a5d7714aed0b25373ec07549349c6db32b6c8c2e43cdd7b1ad2a4154cb5ff1222d9d7010877016a59775abdd2c08f253c850c4048b65cb58e0d58f2dd0f5db3b195c5784933d6179d8317217ba46f9deac9a667bffb1afd0dd86bdae6267af4c2605f7401849a0b980fcecfeae95df7f5ca6e140c406d9b1942c5aa80070ad484b3dd76421a3f46327670bea94e3ecb3a94eef8843a75195b55872a7c503acb01ab368cdaa11a9e5fb80d55bbd6b861233ba84edcf8")
if err != nil { if err != nil {
panic(err) panic(err)
} }
verifScript, err := hex.DecodeString("532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae") verifScript, err := hex.DecodeString("130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b683073b3bb")
if err != nil { if err != nil {
panic(err) panic(err)
} }
sender, err := address.StringToUint160("AZ81H31DMWzbSnFDLFkzh9vHwaDLayV7fU") sender, err := address.StringToUint160("Ad1wDxzcRiRSryvJobNV211Tv7UUiziPXy")
if err != nil { if err != nil {
panic(err) panic(err)
} }
txInvScript, err := hex.DecodeString("40f50121bb6ec9d8e0d1c15eea66b2ff7b51bb1bc4b3da27d9eac1d46b59e6a319bb1db4eb710c7f1931b0c2deaa2389a0fc3fe8c761cec40906b7973450c43173402dc082417a6815e722216de0b857eda6c846bf435088d543d2ab89f1dd92488e87b4d2c6508b0db945cbe6968e85c1c6d57274bfc898e82876c5cb08613da5d64053100f0162a41709a37305c300e7d6ac0d46575aab98dade7375b8d9ca980086594f1288dc68da0e0e42913d1c68024f63442a79c9478971d3ad93c5467ec53040a1c3a772a88b09cba8cc8ec3b46c0c0db6ac86519a7fd7db29b43d34e804a22d8839eaeb35e2a1e05d591fbad4ae290b90c6dc02dddbe28b2b3bf0fec2a337dd") txInvScript, err := hex.DecodeString("0c40ae62dadb95b21628921adb9ee14e8c1f20d68b9d6ffba218f8e403af70126449435a53525cd6f1d1c871e64a91025866cd8a413ec70e3cde0ddf62931aa22baa0c40c3e09fc8ad46789d645240634ef40bd180e0dba75beae07a37dc2e899b68b4b3b3a67d076ea9444ed143dbb3264702914a4662ff95859d32c9b5bb5bdc9ec1d60c40b2511115482bd860d85f57103fb8cce2cb45ba8461d4e164685b426cb5df1525e6f09dd7aa23db0fec2241bde7c925e22f3cba3824ea461455515dc2a1455f5e0c40c0aee2528e7fd75a0434f4d67da58507e8d349ca29e01e7eafa9f283e8b8c05d06587db7234f111730c14c8a4bfb7a1ffd9493b9696c71e68966c6bf4a832ab7")
if err != nil { if err != nil {
panic(err) panic(err)
} }
txVerifScript, err := hex.DecodeString("532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae") txVerifScript, err := hex.DecodeString("130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b683073b3bb")
if err != nil { if err != nil {
panic(err) panic(err)
} }
tx := transaction.NewMinerTXWithNonce(1237) tx := transaction.NewContractTX()
tx.Nonce = 1237
tx.ValidUntilBlock = 5 tx.ValidUntilBlock = 5
tx.Sender = sender tx.Sender = sender
tx.Scripts = []transaction.Witness{ tx.Scripts = []transaction.Witness{
@ -205,16 +206,19 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
_ = tx.Hash() _ = tx.Hash()
return &result.Block{ return &result.Block{
Hash: hash, Hash: hash,
Size: 946, Size: 977,
Version: 0, Version: 0,
NextBlockHash: &nextBlockHash, NextBlockHash: &nextBlockHash,
PreviousBlockHash: prevBlockHash, PreviousBlockHash: prevBlockHash,
MerkleRoot: merkleRoot, MerkleRoot: merkleRoot,
Time: 1587379353, Time: 1587727442,
Index: 5, Index: 5,
Nonce: "0000000000000457", NextConsensus: "Ad1wDxzcRiRSryvJobNV211Tv7UUiziPXy",
NextConsensus: "AZ81H31DMWzbSnFDLFkzh9vHwaDLayV7fU",
Confirmations: 203, Confirmations: 203,
ConsensusData: result.ConsensusData{
PrimaryIndex: 0,
Nonce: "0000000000000457",
},
Script: transaction.Witness{ Script: transaction.Witness{
InvocationScript: invScript, InvocationScript: invScript,
VerificationScript: verifScript, VerificationScript: verifScript,
@ -232,73 +236,74 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
{ {
name: "byHash_positive", name: "byHash_positive",
invoke: func(c *Client) (interface{}, error) { invoke: func(c *Client) (interface{}, error) {
hash, err := util.Uint256DecodeStringLE("0699071a3d86ab915156da98db49a4c3eb34509c6a9ae647aa0edcfb40c1d166") hash, err := util.Uint256DecodeStringLE("e9f71b58764157f1e2c3e29f217e654b57956ee7c8a60496b03ea85e39084b42")
if err != nil { if err != nil {
panic(err) panic(err)
} }
return c.GetBlockByHash(hash) return c.GetBlockByHash(hash)
}, },
serverResponse: `{"id":1,"jsonrpc":"2.0","result":"00000000b3aa04926a237abc2e54808fb10b5ca2394ae5ccfff17d60c1e393cfd418ed8f265f271088384b2f696e34bea0c8e02cf226351800c0866c1586be521536e579997c9d5e050000005704000000000000be48d3a3f5d10013ab9ffee489706078714f1ea201fd040140a6cc2c7fdee4f8fd97f84114d04edda16a37a4c088da9d5be3233e118fccdf73c0305d2cbd15ea0dbcedb594fec3044844e8f59f236ded7fccb1eda2eee2c76740197eba5d648d650ca1d73b8c0a0c7cdc22d31d7b2564764729d271e7ff6378c4f2228f657d65fec530f2af6cdc7af3bc2ab17a7b8175376601fb17ec951faf074038222bb0430f7808d333be3fb8e5b93c490dbb07e6c085350ba64cb7de61127067d1825de30915964dbb345f3b902d61dbf9a294c11ff6459000648f0dc4e66740926854a25b9ea87d7fffe0253bf2bcb3d153434cc0a8ba166136d16aef9a3de70ba3704ba3103a26d01c2bdbeb7262a19bbceab6a7487beba5e55f7ee768a0808b532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae010000d5040000be48d3a3f5d10013ab9ffee489706078714f1ea20500000000000001fd040140f50121bb6ec9d8e0d1c15eea66b2ff7b51bb1bc4b3da27d9eac1d46b59e6a319bb1db4eb710c7f1931b0c2deaa2389a0fc3fe8c761cec40906b7973450c43173402dc082417a6815e722216de0b857eda6c846bf435088d543d2ab89f1dd92488e87b4d2c6508b0db945cbe6968e85c1c6d57274bfc898e82876c5cb08613da5d64053100f0162a41709a37305c300e7d6ac0d46575aab98dade7375b8d9ca980086594f1288dc68da0e0e42913d1c68024f63442a79c9478971d3ad93c5467ec53040a1c3a772a88b09cba8cc8ec3b46c0c0db6ac86519a7fd7db29b43d34e804a22d8839eaeb35e2a1e05d591fbad4ae290b90c6dc02dddbe28b2b3bf0fec2a337dd8b532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae"}`, serverResponse: `{"id":1,"jsonrpc":"2.0","result":"000000005b25cf560918b13cc7a10071cf616426a103d58498171567aaa116af69179aa3c05c359ade4316392d69d5ca01f8860f8bdebbe1a8f752edd68d9a6a2d204fe752cca25e0000000005000000e903736ceceeceae1806eee0e3ec61e7cce476ce01fd08010c407f70912fdcd0ce9a70963110eb39ef73ed02512ea63bc1c55577474df8f364a874999b16666888f8a3ca69873054a31ab42dd1fee1ed8605ff65edb39797e34e0c40d59459cb1cc8270d9a813aa444852a5d7714aed0b25373ec07549349c6db32b6c8c2e43cdd7b1ad2a4154cb5ff1222d9d7010877016a59775abdd2c08f253c850c4048b65cb58e0d58f2dd0f5db3b195c5784933d6179d8317217ba46f9deac9a667bffb1afd0dd86bdae6267af4c2605f7401849a0b980fcecfeae95df7f5ca6e140c406d9b1942c5aa80070ad484b3dd76421a3f46327670bea94e3ecb3a94eef8843a75195b55872a7c503acb01ab368cdaa11a9e5fb80d55bbd6b861233ba84edcf894130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b683073b3bb020057040000000000008000d5040000e903736ceceeceae1806eee0e3ec61e7cce476ce0500000000000001fd08010c40ae62dadb95b21628921adb9ee14e8c1f20d68b9d6ffba218f8e403af70126449435a53525cd6f1d1c871e64a91025866cd8a413ec70e3cde0ddf62931aa22baa0c40c3e09fc8ad46789d645240634ef40bd180e0dba75beae07a37dc2e899b68b4b3b3a67d076ea9444ed143dbb3264702914a4662ff95859d32c9b5bb5bdc9ec1d60c40b2511115482bd860d85f57103fb8cce2cb45ba8461d4e164685b426cb5df1525e6f09dd7aa23db0fec2241bde7c925e22f3cba3824ea461455515dc2a1455f5e0c40c0aee2528e7fd75a0434f4d67da58507e8d349ca29e01e7eafa9f283e8b8c05d06587db7234f111730c14c8a4bfb7a1ffd9493b9696c71e68966c6bf4a832ab794130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b683073b3bb"}`,
result: func(c *Client) interface{} { return &block.Block{} }, result: func(c *Client) interface{} { return &block.Block{} },
check: func(t *testing.T, c *Client, result interface{}) { check: func(t *testing.T, c *Client, result interface{}) {
res, ok := result.(*block.Block) res, ok := result.(*block.Block)
require.True(t, ok) require.True(t, ok)
assert.Equal(t, uint32(0), res.Version) assert.Equal(t, uint32(0), res.Version)
assert.Equal(t, "66d1c140fbdc0eaa47e69a6a9c5034ebc3a449db98da565191ab863d1a079906", res.Hash().StringLE()) assert.Equal(t, "81b74dcfc3a42ef331eec2486231aba300ec9a95b024b0151214c76305d409bb", res.Hash().StringLE())
assert.Equal(t, "8fed18d4cf93e3c1607df1ffcce54a39a25c0bb18f80542ebc7a236a9204aab3", res.PrevHash.StringLE()) assert.Equal(t, "a39a1769af16a1aa6715179884d503a1266461cf7100a1c73cb1180956cf255b", res.PrevHash.StringLE())
assert.Equal(t, "79e5361552be86156c86c000183526f22ce0c8a0be346e692f4b388810275f26", res.MerkleRoot.StringLE()) assert.Equal(t, "e74f202d6a9a8dd6ed52f7a8e1bbde8b0f86f801cad5692d391643de9a355cc0", res.MerkleRoot.StringLE())
assert.Equal(t, 1, len(res.Transactions)) assert.Equal(t, 1, len(res.Transactions))
assert.Equal(t, "79e5361552be86156c86c000183526f22ce0c8a0be346e692f4b388810275f26", res.Transactions[0].Hash().StringLE()) assert.Equal(t, "69d95138263dc54c07826ef1d76f9eb32ff6bf7fc3fc3281194b46ec7683ceb3", res.Transactions[0].Hash().StringLE())
}, },
}, },
{ {
name: "byHash_verbose_positive", name: "byHash_verbose_positive",
invoke: func(c *Client) (i interface{}, err error) { invoke: func(c *Client) (i interface{}, err error) {
hash, err := util.Uint256DecodeStringLE("0699071a3d86ab915156da98db49a4c3eb34509c6a9ae647aa0edcfb40c1d166") hash, err := util.Uint256DecodeStringLE("bb09d40563c7141215b024b0959aec00a3ab316248c2ee31f32ea4c3cf4db781")
if err != nil { if err != nil {
panic(err) panic(err)
} }
return c.GetBlockByHashVerbose(hash) return c.GetBlockByHashVerbose(hash)
}, },
serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"hash":"0x66d1c140fbdc0eaa47e69a6a9c5034ebc3a449db98da565191ab863d1a079906","size":946,"version":0,"nextblockhash":"0xf6749a5eb21273ec67951afd22282f002e605e210678c2fa765dbecf0124bd1a","previousblockhash":"0x8fed18d4cf93e3c1607df1ffcce54a39a25c0bb18f80542ebc7a236a9204aab3","merkleroot":"0x79e5361552be86156c86c000183526f22ce0c8a0be346e692f4b388810275f26","time":1587379353,"index":5,"nonce":"0000000000000457","nextconsensus":"AZ81H31DMWzbSnFDLFkzh9vHwaDLayV7fU","confirmations":203,"script":{"invocation":"40a6cc2c7fdee4f8fd97f84114d04edda16a37a4c088da9d5be3233e118fccdf73c0305d2cbd15ea0dbcedb594fec3044844e8f59f236ded7fccb1eda2eee2c76740197eba5d648d650ca1d73b8c0a0c7cdc22d31d7b2564764729d271e7ff6378c4f2228f657d65fec530f2af6cdc7af3bc2ab17a7b8175376601fb17ec951faf074038222bb0430f7808d333be3fb8e5b93c490dbb07e6c085350ba64cb7de61127067d1825de30915964dbb345f3b902d61dbf9a294c11ff6459000648f0dc4e66740926854a25b9ea87d7fffe0253bf2bcb3d153434cc0a8ba166136d16aef9a3de70ba3704ba3103a26d01c2bdbeb7262a19bbceab6a7487beba5e55f7ee768a080","verification":"532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae"},"tx":[{"sys_fee":"0","net_fee":"0","txid":"0x79e5361552be86156c86c000183526f22ce0c8a0be346e692f4b388810275f26","size":437,"type":"MinerTransaction","version":0,"nonce":1237,"sender":"AZ81H31DMWzbSnFDLFkzh9vHwaDLayV7fU","valid_until_block":5,"attributes":[],"vin":[],"vout":[],"scripts":[{"invocation":"40f50121bb6ec9d8e0d1c15eea66b2ff7b51bb1bc4b3da27d9eac1d46b59e6a319bb1db4eb710c7f1931b0c2deaa2389a0fc3fe8c761cec40906b7973450c43173402dc082417a6815e722216de0b857eda6c846bf435088d543d2ab89f1dd92488e87b4d2c6508b0db945cbe6968e85c1c6d57274bfc898e82876c5cb08613da5d64053100f0162a41709a37305c300e7d6ac0d46575aab98dade7375b8d9ca980086594f1288dc68da0e0e42913d1c68024f63442a79c9478971d3ad93c5467ec53040a1c3a772a88b09cba8cc8ec3b46c0c0db6ac86519a7fd7db29b43d34e804a22d8839eaeb35e2a1e05d591fbad4ae290b90c6dc02dddbe28b2b3bf0fec2a337dd","verification":"532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae"}]}]}}`, serverResponse: `{"id":1,"jsonrpc":"2.0","result":{"hash":"0x81b74dcfc3a42ef331eec2486231aba300ec9a95b024b0151214c76305d409bb","size":977,"version":0,"nextblockhash":"0xd08e408909ae24de3470a3f231f966e15719910cb7b1a30f356b3e784c1ddf6a","previousblockhash":"0xa39a1769af16a1aa6715179884d503a1266461cf7100a1c73cb1180956cf255b","merkleroot":"0xe74f202d6a9a8dd6ed52f7a8e1bbde8b0f86f801cad5692d391643de9a355cc0","time":1587727442,"index":5,"consensus_data":{"primary":0,"nonce":"0000000000000457"},"nextconsensus":"Ad1wDxzcRiRSryvJobNV211Tv7UUiziPXy","confirmations":203,"script":{"invocation":"0c407f70912fdcd0ce9a70963110eb39ef73ed02512ea63bc1c55577474df8f364a874999b16666888f8a3ca69873054a31ab42dd1fee1ed8605ff65edb39797e34e0c40d59459cb1cc8270d9a813aa444852a5d7714aed0b25373ec07549349c6db32b6c8c2e43cdd7b1ad2a4154cb5ff1222d9d7010877016a59775abdd2c08f253c850c4048b65cb58e0d58f2dd0f5db3b195c5784933d6179d8317217ba46f9deac9a667bffb1afd0dd86bdae6267af4c2605f7401849a0b980fcecfeae95df7f5ca6e140c406d9b1942c5aa80070ad484b3dd76421a3f46327670bea94e3ecb3a94eef8843a75195b55872a7c503acb01ab368cdaa11a9e5fb80d55bbd6b861233ba84edcf8","verification":"130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b683073b3bb"},"tx":[{"sys_fee":"0","net_fee":"0","txid":"0x69d95138263dc54c07826ef1d76f9eb32ff6bf7fc3fc3281194b46ec7683ceb3","size":450,"type":"ContractTransaction","version":0,"nonce":1237,"sender":"Ad1wDxzcRiRSryvJobNV211Tv7UUiziPXy","valid_until_block":5,"attributes":[],"vin":[],"vout":[],"scripts":[{"invocation":"0c40ae62dadb95b21628921adb9ee14e8c1f20d68b9d6ffba218f8e403af70126449435a53525cd6f1d1c871e64a91025866cd8a413ec70e3cde0ddf62931aa22baa0c40c3e09fc8ad46789d645240634ef40bd180e0dba75beae07a37dc2e899b68b4b3b3a67d076ea9444ed143dbb3264702914a4662ff95859d32c9b5bb5bdc9ec1d60c40b2511115482bd860d85f57103fb8cce2cb45ba8461d4e164685b426cb5df1525e6f09dd7aa23db0fec2241bde7c925e22f3cba3824ea461455515dc2a1455f5e0c40c0aee2528e7fd75a0434f4d67da58507e8d349ca29e01e7eafa9f283e8b8c05d06587db7234f111730c14c8a4bfb7a1ffd9493b9696c71e68966c6bf4a832ab7","verification":"130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b683073b3bb"}]}]}}`,
result: func(c *Client) interface{} { result: func(c *Client) interface{} {
hash, err := util.Uint256DecodeStringLE("66d1c140fbdc0eaa47e69a6a9c5034ebc3a449db98da565191ab863d1a079906") hash, err := util.Uint256DecodeStringLE("81b74dcfc3a42ef331eec2486231aba300ec9a95b024b0151214c76305d409bb")
if err != nil { if err != nil {
panic(err) panic(err)
} }
nextBlockHash, err := util.Uint256DecodeStringLE("f6749a5eb21273ec67951afd22282f002e605e210678c2fa765dbecf0124bd1a") nextBlockHash, err := util.Uint256DecodeStringLE("d08e408909ae24de3470a3f231f966e15719910cb7b1a30f356b3e784c1ddf6a")
if err != nil { if err != nil {
panic(err) panic(err)
} }
prevBlockHash, err := util.Uint256DecodeStringLE("8fed18d4cf93e3c1607df1ffcce54a39a25c0bb18f80542ebc7a236a9204aab3") prevBlockHash, err := util.Uint256DecodeStringLE("a39a1769af16a1aa6715179884d503a1266461cf7100a1c73cb1180956cf255b")
if err != nil { if err != nil {
panic(err) panic(err)
} }
merkleRoot, err := util.Uint256DecodeStringLE("79e5361552be86156c86c000183526f22ce0c8a0be346e692f4b388810275f26") merkleRoot, err := util.Uint256DecodeStringLE("e74f202d6a9a8dd6ed52f7a8e1bbde8b0f86f801cad5692d391643de9a355cc0")
if err != nil { if err != nil {
panic(err) panic(err)
} }
invScript, err := hex.DecodeString("40a6cc2c7fdee4f8fd97f84114d04edda16a37a4c088da9d5be3233e118fccdf73c0305d2cbd15ea0dbcedb594fec3044844e8f59f236ded7fccb1eda2eee2c76740197eba5d648d650ca1d73b8c0a0c7cdc22d31d7b2564764729d271e7ff6378c4f2228f657d65fec530f2af6cdc7af3bc2ab17a7b8175376601fb17ec951faf074038222bb0430f7808d333be3fb8e5b93c490dbb07e6c085350ba64cb7de61127067d1825de30915964dbb345f3b902d61dbf9a294c11ff6459000648f0dc4e66740926854a25b9ea87d7fffe0253bf2bcb3d153434cc0a8ba166136d16aef9a3de70ba3704ba3103a26d01c2bdbeb7262a19bbceab6a7487beba5e55f7ee768a080") invScript, err := hex.DecodeString("0c407f70912fdcd0ce9a70963110eb39ef73ed02512ea63bc1c55577474df8f364a874999b16666888f8a3ca69873054a31ab42dd1fee1ed8605ff65edb39797e34e0c40d59459cb1cc8270d9a813aa444852a5d7714aed0b25373ec07549349c6db32b6c8c2e43cdd7b1ad2a4154cb5ff1222d9d7010877016a59775abdd2c08f253c850c4048b65cb58e0d58f2dd0f5db3b195c5784933d6179d8317217ba46f9deac9a667bffb1afd0dd86bdae6267af4c2605f7401849a0b980fcecfeae95df7f5ca6e140c406d9b1942c5aa80070ad484b3dd76421a3f46327670bea94e3ecb3a94eef8843a75195b55872a7c503acb01ab368cdaa11a9e5fb80d55bbd6b861233ba84edcf8")
if err != nil { if err != nil {
panic(err) panic(err)
} }
verifScript, err := hex.DecodeString("532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae") verifScript, err := hex.DecodeString("130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b683073b3bb")
if err != nil { if err != nil {
panic(err) panic(err)
} }
sender, err := address.StringToUint160("AZ81H31DMWzbSnFDLFkzh9vHwaDLayV7fU") sender, err := address.StringToUint160("Ad1wDxzcRiRSryvJobNV211Tv7UUiziPXy")
if err != nil { if err != nil {
panic(err) panic(err)
} }
txInvScript, err := hex.DecodeString("40f50121bb6ec9d8e0d1c15eea66b2ff7b51bb1bc4b3da27d9eac1d46b59e6a319bb1db4eb710c7f1931b0c2deaa2389a0fc3fe8c761cec40906b7973450c43173402dc082417a6815e722216de0b857eda6c846bf435088d543d2ab89f1dd92488e87b4d2c6508b0db945cbe6968e85c1c6d57274bfc898e82876c5cb08613da5d64053100f0162a41709a37305c300e7d6ac0d46575aab98dade7375b8d9ca980086594f1288dc68da0e0e42913d1c68024f63442a79c9478971d3ad93c5467ec53040a1c3a772a88b09cba8cc8ec3b46c0c0db6ac86519a7fd7db29b43d34e804a22d8839eaeb35e2a1e05d591fbad4ae290b90c6dc02dddbe28b2b3bf0fec2a337dd") txInvScript, err := hex.DecodeString("0c40ae62dadb95b21628921adb9ee14e8c1f20d68b9d6ffba218f8e403af70126449435a53525cd6f1d1c871e64a91025866cd8a413ec70e3cde0ddf62931aa22baa0c40c3e09fc8ad46789d645240634ef40bd180e0dba75beae07a37dc2e899b68b4b3b3a67d076ea9444ed143dbb3264702914a4662ff95859d32c9b5bb5bdc9ec1d60c40b2511115482bd860d85f57103fb8cce2cb45ba8461d4e164685b426cb5df1525e6f09dd7aa23db0fec2241bde7c925e22f3cba3824ea461455515dc2a1455f5e0c40c0aee2528e7fd75a0434f4d67da58507e8d349ca29e01e7eafa9f283e8b8c05d06587db7234f111730c14c8a4bfb7a1ffd9493b9696c71e68966c6bf4a832ab7")
if err != nil { if err != nil {
panic(err) panic(err)
} }
txVerifScript, err := hex.DecodeString("532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae") txVerifScript, err := hex.DecodeString("130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b683073b3bb")
if err != nil { if err != nil {
panic(err) panic(err)
} }
tx := transaction.NewMinerTXWithNonce(1237) tx := transaction.NewContractTX()
tx.Nonce = 1237
tx.ValidUntilBlock = 5 tx.ValidUntilBlock = 5
tx.Sender = sender tx.Sender = sender
tx.Scripts = []transaction.Witness{ tx.Scripts = []transaction.Witness{
@ -311,16 +316,19 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
_ = tx.Hash() _ = tx.Hash()
return &result.Block{ return &result.Block{
Hash: hash, Hash: hash,
Size: 946, Size: 977,
Version: 0, Version: 0,
NextBlockHash: &nextBlockHash, NextBlockHash: &nextBlockHash,
PreviousBlockHash: prevBlockHash, PreviousBlockHash: prevBlockHash,
MerkleRoot: merkleRoot, MerkleRoot: merkleRoot,
Time: 1587379353, Time: 1587727442,
Index: 5, Index: 5,
Nonce: "0000000000000457", NextConsensus: "Ad1wDxzcRiRSryvJobNV211Tv7UUiziPXy",
NextConsensus: "AZ81H31DMWzbSnFDLFkzh9vHwaDLayV7fU",
Confirmations: 203, Confirmations: 203,
ConsensusData: result.ConsensusData{
PrimaryIndex: 0,
Nonce: "0000000000000457",
},
Script: transaction.Witness{ Script: transaction.Witness{
InvocationScript: invScript, InvocationScript: invScript,
VerificationScript: verifScript, VerificationScript: verifScript,
@ -368,21 +376,21 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
{ {
name: "positive", name: "positive",
invoke: func(c *Client) (interface{}, error) { invoke: func(c *Client) (interface{}, error) {
hash, err := util.Uint256DecodeStringLE("e93d17a52967f9e69314385482bf86f85260e811b46bf4d4b261a7f4135a623c") hash, err := util.Uint256DecodeStringLE("68e4bd688b852e807eef13a0ff7da7b02223e359a35153667e88f9cb4a3b0801")
if err != nil { if err != nil {
panic(err) panic(err)
} }
return c.GetBlockHeader(hash) return c.GetBlockHeader(hash)
}, },
serverResponse: `{"id":1,"jsonrpc":"2.0","result":"00000000999086db552ba8f84734bddca55b25a8d3d8c5f866f941209169c38d35376e99b29ffa96224227f5e033c9a291bceef2724429d596c3a6944cafd6995fdb6dcbe013dd5b010000004ded49fea284b451be48d3a3f5d10013ab9ffee489706078714f1ea201c340356a91d94e398170e47447d6a0f60aa5470e209782a5452403115a49166db3e1c4a3898122db19f779c30f8ccd0b7d401acdf71eda340655e4ae5237a64961bf4034dd47955e5a71627dafc39dd92999140e9eaeec6b11dbb2b313efa3f1093ed915b4455e199c69ec53778f94ffc236b92f8b97fff97a1f6bbb3770c0c0b3844a40fbe743bd5c90b2f5255e0b073281d7aeb2fb516572f36bec8446bcc37ac755cbf10d08b16c95644db1b2dddc2df5daa377880b20198fc7b967ac6e76474b22df8b532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae00"}`, serverResponse: `{"id":1,"jsonrpc":"2.0","result":"00000000d039da5e49d63eb0533437d24ff8ceb6aeacf88680599c39f0ffca8948dfcdb94a3def1fca91cf45d69358414e3be77f7621e557f4cebbdb79a47d3cf56ac007f920a05e0000000001000000d60ac443bb800fb08261e75fa5925d747d48586101fd04014055041db6a59c99ab98137cc57e1e56a0a89856a311b2d2fc0aec76ec714c7616edc8fc5c9b81b27f25b7db1a61f64be0730a9cc103efcea1195cc3fe55843e264027e49c647f48bb08d3c32b79ee3432005ea577d7e497f78b46f1e81858848f961b557fb42a92e8eb4433fed203c917cbebb2138a31ed86750fb769d1e70956c0404c20054aa8bd45b520cba9410a9dd6c256481066bb657d7793fbba5551898c91b6dde81285fac841753ccfdd3193d08f19d5431313fa0d926ca965072a5fa3384026b0705078409bcc62fb98bb985edc387edeaaeba37bb7642d88a90762b2c2a62d9b61d53c097d548a368e450c4d995a178d5af28d4c93698233c52de05e3f0094534c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e4c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd624c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc24c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee6995450683073b3bb00"}`,
result: func(c *Client) interface{} { return &block.Header{} }, result: func(c *Client) interface{} { return &block.Header{} },
check: func(t *testing.T, c *Client, result interface{}) { check: func(t *testing.T, c *Client, result interface{}) {
res, ok := result.(*block.Header) res, ok := result.(*block.Header)
require.True(t, ok) require.True(t, ok)
assert.Equal(t, uint32(0), res.Version) assert.Equal(t, uint32(0), res.Version)
assert.Equal(t, "e93d17a52967f9e69314385482bf86f85260e811b46bf4d4b261a7f4135a623c", res.Hash().StringLE()) assert.Equal(t, "68e4bd688b852e807eef13a0ff7da7b02223e359a35153667e88f9cb4a3b0801", res.Hash().StringLE())
assert.Equal(t, "996e37358dc369912041f966f8c5d8d3a8255ba5dcbd3447f8a82b55db869099", res.PrevHash.StringLE()) assert.Equal(t, "b9cddf4889cafff0399c598086f8acaeb6cef84fd2373453b03ed6495eda39d0", res.PrevHash.StringLE())
assert.Equal(t, "cb6ddb5f99d6af4c94a6c396d5294472f2eebc91a2c933e0f527422296fa9fb2", res.MerkleRoot.StringLE()) assert.Equal(t, "07c06af53c7da479dbbbcef457e521767fe73b4e415893d645cf91ca1fef3d4a", res.MerkleRoot.StringLE())
}, },
}, },
{ {
@ -429,7 +437,6 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
MerkleRoot: merkleRoot, MerkleRoot: merkleRoot,
Timestamp: 1541215200, Timestamp: 1541215200,
Index: 1, Index: 1,
Nonce: "51b484a2fe49ed4d",
NextConsensus: "AZ81H31DMWzbSnFDLFkzh9vHwaDLayV7fU", NextConsensus: "AZ81H31DMWzbSnFDLFkzh9vHwaDLayV7fU",
Confirmations: 20061, Confirmations: 20061,
Script: transaction.Witness{ Script: transaction.Witness{
@ -646,51 +653,52 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
{ {
name: "positive", name: "positive",
invoke: func(c *Client) (i interface{}, err error) { invoke: func(c *Client) (i interface{}, err error) {
hash, err := util.Uint256DecodeStringLE("265f271088384b2f696e34bea0c8e02cf226351800c0866c1586be521536e579") hash, err := util.Uint256DecodeStringLE("b3ce8376ec464b198132fcc37fbff62fb39e6fd7f16e82074cc53d263851d969")
if err != nil { if err != nil {
panic(err) panic(err)
} }
return c.GetRawTransaction(hash) return c.GetRawTransaction(hash)
}, },
serverResponse: `{"id":1,"jsonrpc":"2.0","result":"0000d5040000be48d3a3f5d10013ab9ffee489706078714f1ea20500000000000001fd040140f50121bb6ec9d8e0d1c15eea66b2ff7b51bb1bc4b3da27d9eac1d46b59e6a319bb1db4eb710c7f1931b0c2deaa2389a0fc3fe8c761cec40906b7973450c43173402dc082417a6815e722216de0b857eda6c846bf435088d543d2ab89f1dd92488e87b4d2c6508b0db945cbe6968e85c1c6d57274bfc898e82876c5cb08613da5d64053100f0162a41709a37305c300e7d6ac0d46575aab98dade7375b8d9ca980086594f1288dc68da0e0e42913d1c68024f63442a79c9478971d3ad93c5467ec53040a1c3a772a88b09cba8cc8ec3b46c0c0db6ac86519a7fd7db29b43d34e804a22d8839eaeb35e2a1e05d591fbad4ae290b90c6dc02dddbe28b2b3bf0fec2a337dd8b532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae"}`, serverResponse: `{"id":1,"jsonrpc":"2.0","result":"8000d5040000e903736ceceeceae1806eee0e3ec61e7cce476ce0500000000000001fd08010c40ae62dadb95b21628921adb9ee14e8c1f20d68b9d6ffba218f8e403af70126449435a53525cd6f1d1c871e64a91025866cd8a413ec70e3cde0ddf62931aa22baa0c40c3e09fc8ad46789d645240634ef40bd180e0dba75beae07a37dc2e899b68b4b3b3a67d076ea9444ed143dbb3264702914a4662ff95859d32c9b5bb5bdc9ec1d60c40b2511115482bd860d85f57103fb8cce2cb45ba8461d4e164685b426cb5df1525e6f09dd7aa23db0fec2241bde7c925e22f3cba3824ea461455515dc2a1455f5e0c40c0aee2528e7fd75a0434f4d67da58507e8d349ca29e01e7eafa9f283e8b8c05d06587db7234f111730c14c8a4bfb7a1ffd9493b9696c71e68966c6bf4a832ab794130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b683073b3bb"}`,
result: func(c *Client) interface{} { return &transaction.Transaction{} }, result: func(c *Client) interface{} { return &transaction.Transaction{} },
check: func(t *testing.T, c *Client, result interface{}) { check: func(t *testing.T, c *Client, result interface{}) {
res, ok := result.(*transaction.Transaction) res, ok := result.(*transaction.Transaction)
require.True(t, ok) require.True(t, ok)
assert.Equal(t, uint8(0), res.Version) assert.Equal(t, uint8(0), res.Version)
assert.Equal(t, "265f271088384b2f696e34bea0c8e02cf226351800c0866c1586be521536e579", res.Hash().StringBE()) assert.Equal(t, "b3ce8376ec464b198132fcc37fbff62fb39e6fd7f16e82074cc53d263851d969", res.Hash().StringBE())
assert.Equal(t, transaction.MinerType, res.Type) assert.Equal(t, transaction.ContractType, res.Type)
assert.Equal(t, false, res.Trimmed) assert.Equal(t, false, res.Trimmed)
}, },
}, },
{ {
name: "verbose_positive", name: "verbose_positive",
invoke: func(c *Client) (interface{}, error) { invoke: func(c *Client) (interface{}, error) {
hash, err := util.Uint256DecodeStringLE("265f271088384b2f696e34bea0c8e02cf226351800c0866c1586be521536e579") hash, err := util.Uint256DecodeStringLE("b3ce8376ec464b198132fcc37fbff62fb39e6fd7f16e82074cc53d263851d969")
if err != nil { if err != nil {
panic(err) panic(err)
} }
return c.GetRawTransactionVerbose(hash) return c.GetRawTransactionVerbose(hash)
}, },
serverResponse: `{"jsonrpc":"2.0","id":1,"result":{"sys_fee":"0","net_fee":"0","blockhash":"0x66d1c140fbdc0eaa47e69a6a9c5034ebc3a449db98da565191ab863d1a079906","confirmations":205,"blocktime":1587379353,"txid":"0x79e5361552be86156c86c000183526f22ce0c8a0be346e692f4b388810275f26","size":437,"type":"MinerTransaction","version":0,"nonce":1237,"sender":"AZ81H31DMWzbSnFDLFkzh9vHwaDLayV7fU","valid_until_block":5,"attributes":[],"vin":[],"vout":[],"scripts":[{"invocation":"40f50121bb6ec9d8e0d1c15eea66b2ff7b51bb1bc4b3da27d9eac1d46b59e6a319bb1db4eb710c7f1931b0c2deaa2389a0fc3fe8c761cec40906b7973450c43173402dc082417a6815e722216de0b857eda6c846bf435088d543d2ab89f1dd92488e87b4d2c6508b0db945cbe6968e85c1c6d57274bfc898e82876c5cb08613da5d64053100f0162a41709a37305c300e7d6ac0d46575aab98dade7375b8d9ca980086594f1288dc68da0e0e42913d1c68024f63442a79c9478971d3ad93c5467ec53040a1c3a772a88b09cba8cc8ec3b46c0c0db6ac86519a7fd7db29b43d34e804a22d8839eaeb35e2a1e05d591fbad4ae290b90c6dc02dddbe28b2b3bf0fec2a337dd","verification":"532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae"}]}}`, serverResponse: `{"jsonrpc":"2.0","id":1,"result":{"sys_fee":"0","net_fee":"0","blockhash":"0x81b74dcfc3a42ef331eec2486231aba300ec9a95b024b0151214c76305d409bb","confirmations":205,"blocktime":1587727442,"txid":"0x69d95138263dc54c07826ef1d76f9eb32ff6bf7fc3fc3281194b46ec7683ceb3","size":450,"type":"ContractTransaction","version":0,"nonce":1237,"sender":"Ad1wDxzcRiRSryvJobNV211Tv7UUiziPXy","valid_until_block":5,"attributes":[],"vin":[],"vout":[],"scripts":[{"invocation":"0c40ae62dadb95b21628921adb9ee14e8c1f20d68b9d6ffba218f8e403af70126449435a53525cd6f1d1c871e64a91025866cd8a413ec70e3cde0ddf62931aa22baa0c40c3e09fc8ad46789d645240634ef40bd180e0dba75beae07a37dc2e899b68b4b3b3a67d076ea9444ed143dbb3264702914a4662ff95859d32c9b5bb5bdc9ec1d60c40b2511115482bd860d85f57103fb8cce2cb45ba8461d4e164685b426cb5df1525e6f09dd7aa23db0fec2241bde7c925e22f3cba3824ea461455515dc2a1455f5e0c40c0aee2528e7fd75a0434f4d67da58507e8d349ca29e01e7eafa9f283e8b8c05d06587db7234f111730c14c8a4bfb7a1ffd9493b9696c71e68966c6bf4a832ab7","verification":"130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b683073b3bb"}]}}`,
result: func(c *Client) interface{} { result: func(c *Client) interface{} {
blockHash, err := util.Uint256DecodeStringLE("66d1c140fbdc0eaa47e69a6a9c5034ebc3a449db98da565191ab863d1a079906") blockHash, err := util.Uint256DecodeStringLE("81b74dcfc3a42ef331eec2486231aba300ec9a95b024b0151214c76305d409bb")
if err != nil { if err != nil {
panic(err) panic(err)
} }
sender, err := address.StringToUint160("AZ81H31DMWzbSnFDLFkzh9vHwaDLayV7fU") sender, err := address.StringToUint160("Ad1wDxzcRiRSryvJobNV211Tv7UUiziPXy")
if err != nil { if err != nil {
panic(err) panic(err)
} }
invocation, err := hex.DecodeString("40f50121bb6ec9d8e0d1c15eea66b2ff7b51bb1bc4b3da27d9eac1d46b59e6a319bb1db4eb710c7f1931b0c2deaa2389a0fc3fe8c761cec40906b7973450c43173402dc082417a6815e722216de0b857eda6c846bf435088d543d2ab89f1dd92488e87b4d2c6508b0db945cbe6968e85c1c6d57274bfc898e82876c5cb08613da5d64053100f0162a41709a37305c300e7d6ac0d46575aab98dade7375b8d9ca980086594f1288dc68da0e0e42913d1c68024f63442a79c9478971d3ad93c5467ec53040a1c3a772a88b09cba8cc8ec3b46c0c0db6ac86519a7fd7db29b43d34e804a22d8839eaeb35e2a1e05d591fbad4ae290b90c6dc02dddbe28b2b3bf0fec2a337dd") invocation, err := hex.DecodeString("0c40ae62dadb95b21628921adb9ee14e8c1f20d68b9d6ffba218f8e403af70126449435a53525cd6f1d1c871e64a91025866cd8a413ec70e3cde0ddf62931aa22baa0c40c3e09fc8ad46789d645240634ef40bd180e0dba75beae07a37dc2e899b68b4b3b3a67d076ea9444ed143dbb3264702914a4662ff95859d32c9b5bb5bdc9ec1d60c40b2511115482bd860d85f57103fb8cce2cb45ba8461d4e164685b426cb5df1525e6f09dd7aa23db0fec2241bde7c925e22f3cba3824ea461455515dc2a1455f5e0c40c0aee2528e7fd75a0434f4d67da58507e8d349ca29e01e7eafa9f283e8b8c05d06587db7234f111730c14c8a4bfb7a1ffd9493b9696c71e68966c6bf4a832ab7")
if err != nil { if err != nil {
panic(err) panic(err)
} }
verification, err := hex.DecodeString("532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae") verification, err := hex.DecodeString("130c2102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e0c2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd620c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20c2103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699140b683073b3bb")
if err != nil { if err != nil {
panic(err) panic(err)
} }
tx := transaction.NewMinerTXWithNonce(1237) tx := transaction.NewContractTX()
tx.Nonce = 1237
tx.ValidUntilBlock = 5 tx.ValidUntilBlock = 5
tx.Sender = sender tx.Sender = sender
tx.Scripts = []transaction.Witness{ tx.Scripts = []transaction.Witness{
@ -709,7 +717,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
NetFee: 0, NetFee: 0,
Blockhash: blockHash, Blockhash: blockHash,
Confirmations: 205, Confirmations: 205,
Timestamp: uint32(1587379353), Timestamp: uint64(1587727442),
}, },
} }
}, },
@ -904,7 +912,7 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
{ {
name: "positive", name: "positive",
invoke: func(c *Client) (interface{}, error) { invoke: func(c *Client) (interface{}, error) {
return nil, c.SendRawTransaction(transaction.NewMinerTX()) return nil, c.SendRawTransaction(transaction.NewContractTX())
}, },
serverResponse: `{"jsonrpc":"2.0","id":1,"result":true}`, serverResponse: `{"jsonrpc":"2.0","id":1,"result":true}`,
result: func(c *Client) interface{} { result: func(c *Client) interface{} {
@ -1025,7 +1033,7 @@ var rpcClientErrorCases = map[string][]rpcClientErrorCase{
{ {
name: "sendrawtransaction_bad_server_answer", name: "sendrawtransaction_bad_server_answer",
invoke: func(c *Client) (interface{}, error) { invoke: func(c *Client) (interface{}, error) {
return nil, c.SendRawTransaction(transaction.NewMinerTX()) return nil, c.SendRawTransaction(transaction.NewContractTX())
}, },
}, },
{ {
@ -1411,7 +1419,7 @@ var rpcClientErrorCases = map[string][]rpcClientErrorCase{
{ {
name: "sendrawtransaction_unmarshalling_error", name: "sendrawtransaction_unmarshalling_error",
invoke: func(c *Client) (interface{}, error) { invoke: func(c *Client) (interface{}, error) {
return nil, c.SendRawTransaction(transaction.NewMinerTX()) return nil, c.SendRawTransaction(transaction.NewContractTX())
}, },
}, },
{ {

View file

@ -27,6 +27,12 @@ type (
NetFee util.Fixed8 `json:"net_fee"` NetFee util.Fixed8 `json:"net_fee"`
} }
// ConsensusData is a wrapper for block.ConsensusData
ConsensusData struct {
PrimaryIndex uint32 `json:"primary"`
Nonce string `json:"nonce"`
}
// Block wrapper used for the representation of // Block wrapper used for the representation of
// block.Block / block.Base on the RPC Server. // block.Block / block.Base on the RPC Server.
Block struct { Block struct {
@ -36,9 +42,9 @@ type (
NextBlockHash *util.Uint256 `json:"nextblockhash,omitempty"` NextBlockHash *util.Uint256 `json:"nextblockhash,omitempty"`
PreviousBlockHash util.Uint256 `json:"previousblockhash"` PreviousBlockHash util.Uint256 `json:"previousblockhash"`
MerkleRoot util.Uint256 `json:"merkleroot"` MerkleRoot util.Uint256 `json:"merkleroot"`
Time uint32 `json:"time"` Time uint64 `json:"time"`
Index uint32 `json:"index"` Index uint32 `json:"index"`
Nonce string `json:"nonce"` ConsensusData ConsensusData `json:"consensus_data"`
NextConsensus string `json:"nextconsensus"` NextConsensus string `json:"nextconsensus"`
Confirmations uint32 `json:"confirmations"` Confirmations uint32 `json:"confirmations"`
@ -59,7 +65,10 @@ func NewBlock(b *block.Block, chain blockchainer.Blockchainer) Block {
MerkleRoot: b.MerkleRoot, MerkleRoot: b.MerkleRoot,
Time: b.Timestamp, Time: b.Timestamp,
Index: b.Index, Index: b.Index,
Nonce: fmt.Sprintf("%016x", b.ConsensusData), ConsensusData: ConsensusData{
PrimaryIndex: b.ConsensusData.PrimaryIndex,
Nonce: fmt.Sprintf("%016x", b.ConsensusData.Nonce),
},
NextConsensus: address.Uint160ToString(b.NextConsensus), NextConsensus: address.Uint160ToString(b.NextConsensus),
Confirmations: chain.BlockHeight() - b.Index - 1, Confirmations: chain.BlockHeight() - b.Index - 1,

View file

@ -1,8 +1,6 @@
package result package result
import ( import (
"strconv"
"github.com/nspcc-dev/neo-go/pkg/core/block" "github.com/nspcc-dev/neo-go/pkg/core/block"
"github.com/nspcc-dev/neo-go/pkg/core/blockchainer" "github.com/nspcc-dev/neo-go/pkg/core/blockchainer"
"github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/core/transaction"
@ -20,9 +18,8 @@ type (
Version uint32 `json:"version"` Version uint32 `json:"version"`
PrevBlockHash util.Uint256 `json:"previousblockhash"` PrevBlockHash util.Uint256 `json:"previousblockhash"`
MerkleRoot util.Uint256 `json:"merkleroot"` MerkleRoot util.Uint256 `json:"merkleroot"`
Timestamp uint32 `json:"time"` Timestamp uint64 `json:"time"`
Index uint32 `json:"index"` Index uint32 `json:"index"`
Nonce string `json:"nonce"`
NextConsensus string `json:"nextconsensus"` NextConsensus string `json:"nextconsensus"`
Script transaction.Witness `json:"script"` Script transaction.Witness `json:"script"`
Confirmations uint32 `json:"confirmations"` Confirmations uint32 `json:"confirmations"`
@ -40,7 +37,6 @@ func NewHeader(h *block.Header, chain blockchainer.Blockchainer) Header {
MerkleRoot: h.MerkleRoot, MerkleRoot: h.MerkleRoot,
Timestamp: h.Timestamp, Timestamp: h.Timestamp,
Index: h.Index, Index: h.Index,
Nonce: strconv.FormatUint(h.ConsensusData, 16),
NextConsensus: address.Uint160ToString(h.NextConsensus), NextConsensus: address.Uint160ToString(h.NextConsensus),
Script: h.Script, Script: h.Script,
Confirmations: chain.BlockHeight() - h.Index + 1, Confirmations: chain.BlockHeight() - h.Index + 1,

View file

@ -35,7 +35,7 @@ type NEP5Transfers struct {
// NEP5Transfer represents single NEP5 transfer event. // NEP5Transfer represents single NEP5 transfer event.
type NEP5Transfer struct { type NEP5Transfer struct {
Timestamp uint32 `json:"timestamp"` Timestamp uint64 `json:"timestamp"`
Asset util.Uint160 `json:"asset_hash"` Asset util.Uint160 `json:"asset_hash"`
Address string `json:"transfer_address,omitempty"` Address string `json:"transfer_address,omitempty"`
Amount string `json:"amount"` Amount string `json:"amount"`

View file

@ -23,7 +23,7 @@ type TransactionMetadata struct {
NetFee util.Fixed8 `json:"net_fee"` NetFee util.Fixed8 `json:"net_fee"`
Blockhash util.Uint256 `json:"blockhash,omitempty"` Blockhash util.Uint256 `json:"blockhash,omitempty"`
Confirmations int `json:"confirmations,omitempty"` Confirmations int `json:"confirmations,omitempty"`
Timestamp uint32 `json:"blocktime,omitempty"` Timestamp uint64 `json:"blocktime,omitempty"`
} }
// NewTransactionOutputRaw returns a new ransactionOutputRaw object. // NewTransactionOutputRaw returns a new ransactionOutputRaw object.

View file

@ -9,7 +9,6 @@ import (
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"reflect" "reflect"
"strconv"
"strings" "strings"
"testing" "testing"
"time" "time"
@ -54,12 +53,12 @@ var rpcTestCases = map[string][]rpcTestCase{
"getapplicationlog": { "getapplicationlog": {
{ {
name: "positive", name: "positive",
params: `["4108062977676178e8453a8ef84a702e01bb35af8a65c7529d04704fcb5f1e0e"]`, params: `["fe1a3678b16eca35209acf85397708eb0f1668e4045ad4cd5d2453d3bc0a0a6d"]`,
result: func(e *executor) interface{} { return &result.ApplicationLog{} }, result: func(e *executor) interface{} { return &result.ApplicationLog{} },
check: func(t *testing.T, e *executor, acc interface{}) { check: func(t *testing.T, e *executor, acc interface{}) {
res, ok := acc.(*result.ApplicationLog) res, ok := acc.(*result.ApplicationLog)
require.True(t, ok) require.True(t, ok)
expectedTxHash, err := util.Uint256DecodeStringLE("4108062977676178e8453a8ef84a702e01bb35af8a65c7529d04704fcb5f1e0e") expectedTxHash, err := util.Uint256DecodeStringLE("fe1a3678b16eca35209acf85397708eb0f1668e4045ad4cd5d2453d3bc0a0a6d")
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, expectedTxHash, res.TxHash) assert.Equal(t, expectedTxHash, res.TxHash)
assert.Equal(t, 1, len(res.Executions)) assert.Equal(t, 1, len(res.Executions))
@ -339,11 +338,11 @@ var rpcTestCases = map[string][]rpcTestCase{
assert.Equal(t, block.Hash(), res.Hash) assert.Equal(t, block.Hash(), res.Hash)
for i := range res.Tx { for i := range res.Tx {
tx := res.Tx[i] tx := res.Tx[i]
require.Equal(t, transaction.MinerType, tx.Transaction.Type) require.Equal(t, transaction.ContractType, tx.Transaction.Type)
miner := block.Transactions[i] actualTx := block.Transactions[i]
require.True(t, ok) require.True(t, ok)
require.Equal(t, miner.Nonce, tx.Transaction.Nonce) require.Equal(t, actualTx.Nonce, tx.Transaction.Nonce)
require.Equal(t, block.Transactions[i].Hash(), tx.Transaction.Hash()) require.Equal(t, block.Transactions[i].Hash(), tx.Transaction.Hash())
} }
}, },
@ -744,7 +743,7 @@ var rpcTestCases = map[string][]rpcTestCase{
"sendrawtransaction": { "sendrawtransaction": {
{ {
name: "positive", name: "positive",
params: `["80001300000075a94799633ed955dd85a8af314a5b435ab51903b00400000001eb15931b0544cbb9a283f934ab89a23e73cf90b9ca097bb327a0bcdcddf8ce2e010001f5bc5a9ac7b85a47be381260a06b5a1e7a667ce8f7d7c8baa5cfc6465571377a0030d3dec386230075a94799633ed955dd85a8af314a5b435ab5190301420c4082632495e555507a056eae951ad1893f27163dde40505340f6cf9578e20c3d7ec0c7e00f93cb2e770a7ce3e8a2910deabdd01fd966507a7a29106dd2add583ee290c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b680a906ad4"]`, params: `["80000b00000075a94799633ed955dd85a8af314a5b435ab51903b004000000011e4db58df4326140a371d0b0cabecea70226b93157dfb561c73ba8db599ebcb6010001f5bc5a9ac7b85a47be381260a06b5a1e7a667ce8f7d7c8baa5cfc6465571377a0030d3dec386230075a94799633ed955dd85a8af314a5b435ab5190301420c401b3040b6eea83bfbd555554c94e7a0e6077922769f3ac19c1183e14dfd1d6ef6a87658b5499921ac59ae2d2acac10d8f0f6147620e27616bb5b7305fb36b6ce0290c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b680a906ad4"]`,
result: func(e *executor) interface{} { result: func(e *executor) interface{} {
v := true v := true
return &v return &v
@ -858,7 +857,8 @@ func TestRPC(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
newTx := func() *transaction.Transaction { newTx := func() *transaction.Transaction {
height := chain.BlockHeight() height := chain.BlockHeight()
tx := transaction.NewMinerTXWithNonce(height + 1) tx := transaction.NewContractTX()
tx.Nonce = height + 1
tx.ValidUntilBlock = height + 10 tx.ValidUntilBlock = height + 10
tx.Sender = acc.PrivateKey().GetScriptHash() tx.Sender = acc.PrivateKey().GetScriptHash()
require.NoError(t, acc.SignTx(tx)) require.NoError(t, acc.SignTx(tx))
@ -883,7 +883,7 @@ func TestRPC(t *testing.T) {
t.Run("getrawtransaction", func(t *testing.T) { t.Run("getrawtransaction", func(t *testing.T) {
block, _ := chain.GetBlock(chain.GetHeaderHash(0)) block, _ := chain.GetBlock(chain.GetHeaderHash(0))
TXHash := block.Transactions[1].Hash() TXHash := block.Transactions[0].Hash()
rpc := fmt.Sprintf(`{"jsonrpc": "2.0", "id": 1, "method": "getrawtransaction", "params": ["%s"]}"`, TXHash.StringLE()) rpc := fmt.Sprintf(`{"jsonrpc": "2.0", "id": 1, "method": "getrawtransaction", "params": ["%s"]}"`, TXHash.StringLE())
body := doRPCCall(rpc, handler, t) body := doRPCCall(rpc, handler, t)
result := checkErrGetResult(t, body, false) result := checkErrGetResult(t, body, false)
@ -895,7 +895,7 @@ func TestRPC(t *testing.T) {
t.Run("getrawtransaction 2 arguments", func(t *testing.T) { t.Run("getrawtransaction 2 arguments", func(t *testing.T) {
block, _ := chain.GetBlock(chain.GetHeaderHash(0)) block, _ := chain.GetBlock(chain.GetHeaderHash(0))
TXHash := block.Transactions[1].Hash() TXHash := block.Transactions[0].Hash()
rpc := fmt.Sprintf(`{"jsonrpc": "2.0", "id": 1, "method": "getrawtransaction", "params": ["%s", 0]}"`, TXHash.StringLE()) rpc := fmt.Sprintf(`{"jsonrpc": "2.0", "id": 1, "method": "getrawtransaction", "params": ["%s", 0]}"`, TXHash.StringLE())
body := doRPCCall(rpc, handler, t) body := doRPCCall(rpc, handler, t)
result := checkErrGetResult(t, body, false) result := checkErrGetResult(t, body, false)
@ -907,7 +907,7 @@ func TestRPC(t *testing.T) {
t.Run("getrawtransaction 2 arguments, verbose", func(t *testing.T) { t.Run("getrawtransaction 2 arguments, verbose", func(t *testing.T) {
block, _ := chain.GetBlock(chain.GetHeaderHash(0)) block, _ := chain.GetBlock(chain.GetHeaderHash(0))
TXHash := block.Transactions[1].Hash() TXHash := block.Transactions[0].Hash()
rpc := fmt.Sprintf(`{"jsonrpc": "2.0", "id": 1, "method": "getrawtransaction", "params": ["%s", 1]}"`, TXHash.StringLE()) rpc := fmt.Sprintf(`{"jsonrpc": "2.0", "id": 1, "method": "getrawtransaction", "params": ["%s", 1]}"`, TXHash.StringLE())
body := doRPCCall(rpc, handler, t) body := doRPCCall(rpc, handler, t)
txOut := checkErrGetResult(t, body, false) txOut := checkErrGetResult(t, body, false)
@ -967,7 +967,6 @@ func TestRPC(t *testing.T) {
MerkleRoot: hdr.MerkleRoot, MerkleRoot: hdr.MerkleRoot,
Timestamp: hdr.Timestamp, Timestamp: hdr.Timestamp,
Index: hdr.Index, Index: hdr.Index,
Nonce: strconv.FormatUint(hdr.ConsensusData, 16),
NextConsensus: address.Uint160ToString(hdr.NextConsensus), NextConsensus: address.Uint160ToString(hdr.NextConsensus),
Script: hdr.Script, Script: hdr.Script,
Confirmations: e.chain.BlockHeight() - hdr.Index + 1, Confirmations: e.chain.BlockHeight() - hdr.Index + 1,
@ -981,7 +980,8 @@ func TestRPC(t *testing.T) {
t.Run("gettxout", func(t *testing.T) { t.Run("gettxout", func(t *testing.T) {
block, _ := chain.GetBlock(chain.GetHeaderHash(0)) block, _ := chain.GetBlock(chain.GetHeaderHash(0))
tx := block.Transactions[3] require.Equal(t, 4, len(block.Transactions))
tx := block.Transactions[2]
rpc := fmt.Sprintf(`{"jsonrpc": "2.0", "id": 1, "method": "gettxout", "params": [%s, %d]}"`, rpc := fmt.Sprintf(`{"jsonrpc": "2.0", "id": 1, "method": "gettxout", "params": [%s, %d]}"`,
`"`+tx.Hash().StringLE()+`"`, 0) `"`+tx.Hash().StringLE()+`"`, 0)
body := doRPCCall(rpc, handler, t) body := doRPCCall(rpc, handler, t)
@ -1004,7 +1004,7 @@ func TestRPC(t *testing.T) {
expected = append(expected, tx.Tx.Hash()) expected = append(expected, tx.Tx.Hash())
} }
for i := 0; i < 5; i++ { for i := 0; i < 5; i++ {
tx := transaction.NewMinerTX() tx := transaction.NewContractTX()
assert.NoError(t, mp.Add(tx, &FeerStub{})) assert.NoError(t, mp.Add(tx, &FeerStub{}))
expected = append(expected, tx.Hash()) expected = append(expected, tx.Hash())
} }
@ -1049,12 +1049,15 @@ func newBlock(t *testing.T, bc blockchainer.Blockchainer, index uint32, txs ...*
b := &block.Block{ b := &block.Block{
Base: block.Base{ Base: block.Base{
PrevHash: hdr.Hash(), PrevHash: hdr.Hash(),
Timestamp: uint32(time.Now().UTC().Unix()) + hdr.Index, Timestamp: (uint64(time.Now().UTC().Unix()) + uint64(hdr.Index)) * 1000,
Index: hdr.Index + index, Index: hdr.Index + index,
ConsensusData: 1111,
NextConsensus: witness.ScriptHash(), NextConsensus: witness.ScriptHash(),
Script: witness, Script: witness,
}, },
ConsensusData: block.ConsensusData{
PrimaryIndex: 0,
Nonce: 1111,
},
Transactions: txs, Transactions: txs,
} }
_ = b.RebuildMerkleRoot() _ = b.RebuildMerkleRoot()

Binary file not shown.