2020-01-14 12:32:07 +00:00
|
|
|
package block
|
2018-02-01 20:28:45 +00:00
|
|
|
|
2018-02-04 19:54:51 +00:00
|
|
|
import (
|
|
|
|
"encoding/hex"
|
|
|
|
"testing"
|
2018-02-01 20:28:45 +00:00
|
|
|
|
2018-03-04 13:56:49 +00:00
|
|
|
"github.com/CityOfZion/neo-go/pkg/core/transaction"
|
2019-10-15 09:52:10 +00:00
|
|
|
"github.com/CityOfZion/neo-go/pkg/crypto/hash"
|
2019-12-25 12:22:02 +00:00
|
|
|
"github.com/CityOfZion/neo-go/pkg/encoding/address"
|
2019-09-16 09:18:13 +00:00
|
|
|
"github.com/CityOfZion/neo-go/pkg/io"
|
2018-03-09 15:55:25 +00:00
|
|
|
"github.com/stretchr/testify/assert"
|
2020-01-15 08:35:02 +00:00
|
|
|
"github.com/stretchr/testify/require"
|
2018-02-04 19:54:51 +00:00
|
|
|
)
|
|
|
|
|
2018-03-17 11:53:21 +00:00
|
|
|
// Test blocks are blocks from mainnet with their corresponding index.
|
|
|
|
|
|
|
|
func TestDecodeBlock1(t *testing.T) {
|
|
|
|
data, err := getBlockData(1)
|
2020-01-15 08:35:02 +00:00
|
|
|
require.NoError(t, err)
|
2018-02-04 19:54:51 +00:00
|
|
|
|
2018-03-17 11:53:21 +00:00
|
|
|
b, err := hex.DecodeString(data["raw"].(string))
|
2020-01-15 08:35:02 +00:00
|
|
|
require.NoError(t, err)
|
2018-02-04 19:54:51 +00:00
|
|
|
|
|
|
|
block := &Block{}
|
2019-09-16 16:31:49 +00:00
|
|
|
r := io.NewBinReaderFromBuf(b)
|
|
|
|
block.DecodeBinary(r)
|
|
|
|
assert.Nil(t, r.Err)
|
2018-03-17 11:53:21 +00:00
|
|
|
|
|
|
|
assert.Equal(t, uint32(data["index"].(float64)), block.Index)
|
|
|
|
assert.Equal(t, uint32(data["version"].(float64)), block.Version)
|
2019-11-27 09:23:18 +00:00
|
|
|
assert.Equal(t, data["hash"].(string), block.Hash().StringLE())
|
|
|
|
assert.Equal(t, data["previousblockhash"].(string), block.PrevHash.StringLE())
|
|
|
|
assert.Equal(t, data["merkleroot"].(string), block.MerkleRoot.StringLE())
|
2019-12-25 14:34:18 +00:00
|
|
|
assert.Equal(t, data["nextconsensus"].(string), address.Uint160ToString(block.NextConsensus))
|
2018-03-17 11:53:21 +00:00
|
|
|
|
|
|
|
script := data["script"].(map[string]interface{})
|
|
|
|
assert.Equal(t, script["invocation"].(string), hex.EncodeToString(block.Script.InvocationScript))
|
|
|
|
assert.Equal(t, script["verification"].(string), hex.EncodeToString(block.Script.VerificationScript))
|
|
|
|
|
|
|
|
tx := data["tx"].([]interface{})
|
|
|
|
minerTX := tx[0].(map[string]interface{})
|
|
|
|
assert.Equal(t, len(tx), len(block.Transactions))
|
|
|
|
assert.Equal(t, minerTX["type"].(string), block.Transactions[0].Type.String())
|
|
|
|
assert.Equal(t, len(minerTX["attributes"].([]interface{})), len(block.Transactions[0].Attributes))
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestTrimmedBlock(t *testing.T) {
|
|
|
|
block := getDecodedBlock(t, 1)
|
|
|
|
|
|
|
|
b, err := block.Trim()
|
2020-01-15 08:35:02 +00:00
|
|
|
require.NoError(t, err)
|
2018-03-17 11:53:21 +00:00
|
|
|
|
|
|
|
trimmedBlock, err := NewBlockFromTrimmedBytes(b)
|
2020-01-15 08:35:02 +00:00
|
|
|
require.NoError(t, err)
|
2018-03-17 11:53:21 +00:00
|
|
|
|
|
|
|
assert.True(t, trimmedBlock.Trimmed)
|
|
|
|
assert.Equal(t, block.Version, trimmedBlock.Version)
|
|
|
|
assert.Equal(t, block.PrevHash, trimmedBlock.PrevHash)
|
|
|
|
assert.Equal(t, block.MerkleRoot, trimmedBlock.MerkleRoot)
|
|
|
|
assert.Equal(t, block.Timestamp, trimmedBlock.Timestamp)
|
|
|
|
assert.Equal(t, block.Index, trimmedBlock.Index)
|
|
|
|
assert.Equal(t, block.ConsensusData, trimmedBlock.ConsensusData)
|
|
|
|
assert.Equal(t, block.NextConsensus, trimmedBlock.NextConsensus)
|
|
|
|
|
|
|
|
assert.Equal(t, block.Script, trimmedBlock.Script)
|
|
|
|
assert.Equal(t, len(block.Transactions), len(trimmedBlock.Transactions))
|
|
|
|
for i := 0; i < len(block.Transactions); i++ {
|
|
|
|
assert.Equal(t, block.Transactions[i].Hash(), trimmedBlock.Transactions[i].Hash())
|
|
|
|
assert.True(t, trimmedBlock.Transactions[i].Trimmed)
|
|
|
|
}
|
2018-02-04 19:54:51 +00:00
|
|
|
}
|
|
|
|
|
2019-10-15 09:52:10 +00:00
|
|
|
func newDumbBlock() *Block {
|
|
|
|
return &Block{
|
2020-01-15 08:29:50 +00:00
|
|
|
Base: Base{
|
2019-10-15 09:52:10 +00:00
|
|
|
Version: 0,
|
|
|
|
PrevHash: hash.Sha256([]byte("a")),
|
|
|
|
MerkleRoot: hash.Sha256([]byte("b")),
|
|
|
|
Timestamp: uint32(100500),
|
|
|
|
Index: 1,
|
|
|
|
ConsensusData: 1111,
|
|
|
|
NextConsensus: hash.Hash160([]byte("a")),
|
2019-12-09 14:14:10 +00:00
|
|
|
Script: transaction.Witness{
|
2019-10-15 09:52:10 +00:00
|
|
|
VerificationScript: []byte{0x51}, // PUSH1
|
|
|
|
InvocationScript: []byte{0x61}, // NOP
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Transactions: []*transaction.Transaction{
|
|
|
|
{Type: transaction.MinerType},
|
|
|
|
{Type: transaction.IssueType},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-04 19:54:51 +00:00
|
|
|
func TestHashBlockEqualsHashHeader(t *testing.T) {
|
2019-10-15 09:52:10 +00:00
|
|
|
block := newDumbBlock()
|
|
|
|
|
2018-03-09 15:55:25 +00:00
|
|
|
assert.Equal(t, block.Hash(), block.Header().Hash())
|
2018-02-04 19:54:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestBlockVerify(t *testing.T) {
|
2019-10-15 09:52:10 +00:00
|
|
|
block := newDumbBlock()
|
|
|
|
assert.NotNil(t, block.Verify())
|
2020-01-14 12:32:07 +00:00
|
|
|
assert.Nil(t, block.RebuildMerkleRoot())
|
2019-10-15 09:52:10 +00:00
|
|
|
assert.Nil(t, block.Verify())
|
2018-02-04 19:54:51 +00:00
|
|
|
|
2018-03-04 13:56:49 +00:00
|
|
|
block.Transactions = []*transaction.Transaction{
|
|
|
|
{Type: transaction.IssueType},
|
|
|
|
{Type: transaction.MinerType},
|
2018-02-04 19:54:51 +00:00
|
|
|
}
|
2020-01-14 12:32:07 +00:00
|
|
|
assert.NoError(t, block.RebuildMerkleRoot())
|
2019-10-15 09:52:10 +00:00
|
|
|
assert.NotNil(t, block.Verify())
|
2018-02-04 19:54:51 +00:00
|
|
|
|
2018-03-04 13:56:49 +00:00
|
|
|
block.Transactions = []*transaction.Transaction{
|
|
|
|
{Type: transaction.MinerType},
|
|
|
|
{Type: transaction.MinerType},
|
2018-02-04 19:54:51 +00:00
|
|
|
}
|
2020-01-14 12:32:07 +00:00
|
|
|
assert.NoError(t, block.RebuildMerkleRoot())
|
2019-10-15 09:52:10 +00:00
|
|
|
assert.NotNil(t, block.Verify())
|
|
|
|
block.Transactions = []*transaction.Transaction{
|
|
|
|
{Type: transaction.MinerType},
|
|
|
|
{Type: transaction.IssueType},
|
|
|
|
{Type: transaction.IssueType},
|
|
|
|
}
|
|
|
|
assert.NotNil(t, block.Verify())
|
2018-03-09 15:55:25 +00:00
|
|
|
}
|
2019-08-30 08:29:59 +00:00
|
|
|
|
|
|
|
func TestBinBlockDecodeEncode(t *testing.T) {
|
|
|
|
// transaction taken from mainnet: 2000000
|
|
|
|
rawtx := "00000000e5a49e24ee36e972e1bbee16c6897b88050e95e40db157d901cbb68de5243dc93482b51e7ce810eca512afe201768668de5910d4373db067418ad1cf95cd291de424a15a80841e00ec3bd62b5562099d59e75d652b5d3827bf04c165bbe9ef95cca4bf5501fd450140f9ef37e9a31614d0c42aca576d11fcd2ca4cade56143e725ab45e2c7372601e5322a89e0585b44f6f436147be6dc6513ebe781c358abadb1336cadc8f1fdf2e4407fedf529ec4b16ada7fec16efcb377e9c0ea515b12b98a8bed01c385999f8f6121dd5fad32abe4d95dc0c11e9a3a6ce093a7f550b96b779c45f584022bb8a93640d266010bee43509f70c9e7d86cd5037214718de5682abeb42141d1691a1595e5ee188393c26b9ca9f31e4db2d87c3c76869c4b02d081672909268e4d53bcc850401866a84eafd9003c17f1469f1830c5c5f2976da54991f7a1ed292a8af0de2ce202d8f15cb0f362f0ae0ee8bf43886785db45fed0d77b5254503ac105e694a7ac40bfc7166d3495ad4ab540e287ec51afc0569f292e106055b13765d6dacc1ed14807eb63cfeb04b50977c2a64735a4d7496c95f361b773dc58ae29a11b8183f717f1552102486fd15702c4490a26703112a5cc1d0923fd697a33406bd5a1c00e0013b09a7021024c7b7fb6c310fccf1ba33b082519d82964ea93868d676662d4a59ad548df0e7d2102aaec38470f6aad0042c6e877cfd8087d2676b0f516fddd362801b9bd3936399e2103b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c2103b8d9d5771d8f513aa0869b9cc8d50986403b78c6da36890638c3d46a5adce04a2102ca0e27697b9c248f6f16e085fd0061e26f44da85b58ee835c110caa5ec3ba5542102df48f60e8f3e01c48ff40b9b7f1310d7a8b2a193188befe1c2e3df740e89509357ae120000ec3bd62b0000000080000001e91406db8ce12ff273d9c04cb0f224870d43eeb53c7522a6ad47b0c2ad9614cc0000019b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc5005ed0b200000000606fe152cafd010c1911b9c7932b77562d13b02f01414054f533865c49ae27ee9898f18c3ad18e2bb27928af9dbfdca44713b666f343e06416fe04869c3b5355934b101ac40caa4910cebdcfc3fec7322d12b0aa4d5bd7232103dfe98cbad29e3116324a5125a32b36250679190f74dca7425c40fff589cc530cac800000012ae528ca6f1c1a740a716603aac1e167cad482d49c41e4a356565cefa50b5dbd0000019b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc5008d190207000000be87c8c3cb58ca27e5235c5d451474435b895386014140fe20765111b9845d7d842cf09205931ea35e0de5d7078c3831e2b36e41e2298a1cf3d8bc697676ae48a577d70757ecf262085ed314c2d077e0e7a11830dc1b7d232103f2ad7aebe26d46541cb99deb3ff06fd24f0b87efa7e52a1aba6a2d3167be6044acd1015b0600a0724e1809146063795d3b9b3cd55aef026eae992b91063db0db1458f310994f5561f8759ebbdab2e87a05fa4d256553c1087472616e7366657267f91d6b7085db7c5aaf09f19eeec1ca3c0db2c6ecf166aacd14a39b8747f90000000000000000012058f310994f5561f8759ebbdab2e87a05fa4d25650000014140664803b370fb1125fccb44b470a9062d2f1108f4b9c43b7aa35fd56eb52c0564c72e649eefacf82bfb25d252aef5e677307bd0142cecc60e369265b3d053a8d9232103a95af1ee45fe9a2cbad6358e3357da7a13e994361b385c72141ca5a47ef993f6ac800000028190ef017f831707830dd8dc2867572136e7d73bdc13a7421433072e36830c6c00008190ef017f831707830dd8dc2867572136e7d73bdc13a7421433072e36830c6c010001e72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c600300000000000000494a6c348bdcbf192fb1a88ee41883fcdd11ef37014140a2dc5f161bcb696deeae6f078702627280cfc360d5bf0cae13a417212da2bc87c207d58cca83deb3e6fd76c05bc135367eb520e0138fbfc25e05985ddfa514352321039beeb554e21dfdd414fd07844460d2d1117d26e6b6d18314c535ef25511cee16ac8000000144a1e8637a27d17be06f4d5e4483841c5db27420757350833e970861cf0f6c650500019b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc500c817a80400000034a3393450b5217977ba2efebad0dd6c37bb0a690141409f6eec2a9983ae782e3d7bdf8ce02f2c9b6db4660ee93197ed8ae85ae9ef424d421ba35a3b70738618b255ab387fe32a0dee1ccd6c0bb8d1e306e3947c383557232103994c84c3cbbc3a75be1045a2ce795d2d5733bb8425f2580e19ff7f179bb8719bac80000001e04c80df4a53b8ba9dca435630f1170d3cc6f15f508e98006ef44bf9f38de82d0000019b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc500bca06501000000d32f28fd47cc176e3d2bf6ac30eb87dfb838ef99014140b8c50990b976e837033eb09da821dae396782bd0df404e1e0675f2db9b7fc6b681b1cb6cb717a546268363f63ae65f89a18769d201b531fee4afd78b2fffb9aa232103ef4c441d2c4cd1a2e3f255366d149553a7f8f799edf1a49a0bc1af0081cc65beac80000001a6f0562becc89fd0ab4c36e2bcc4eedeb6de9fa6bb398be22dafc4e0512b55bc0000019b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc50001b2c4000000001decb55a
|
|
|
|
rawtxBytes, _ := hex.DecodeString(rawtx)
|
|
|
|
|
|
|
|
b := Block{}
|
|
|
|
|
2019-09-16 09:18:13 +00:00
|
|
|
r := io.NewBinReaderFromBuf(rawtxBytes)
|
2019-09-16 16:31:49 +00:00
|
|
|
b.DecodeBinary(r)
|
|
|
|
assert.Nil(t, r.Err)
|
2019-08-30 08:29:59 +00:00
|
|
|
expected := map[string]bool{ // 18 trans
|
|
|
|
|
|
|
|
"009f61f481f47eb7478e887871e4e744669d461b13d68e04250035260171d706": false,
|
|
|
|
"3a62e473c1d67ac561b98e8131f7f7ceded4cd250edb78a6814ec9915930ad93": false,
|
|
|
|
"d56a545d2f9400c09d5aa4e8cc37cc994d5a6892f9c30de95ff69a3b647b27a2": false,
|
|
|
|
"57f6baa9cb23ce9117d66aee7c31ba6d1e82e140a805db1c5992ada849f6a7c7": false,
|
|
|
|
"f700be9c723ed44900ac9d70874b9d8601033bb78883c0a43ab38b5d96c09c11": false,
|
|
|
|
"31674ac8553b371ddf06db6a3aef09b8d6f37da03a8cc2868b71044c54ef0034": false,
|
|
|
|
"44858de48ec97cea2f823128e9d58981dde11f28a6ebf0a2cb745ea13223dd71": false,
|
|
|
|
"317f3ff3768b2aebe3d4866f6e0e8b875cc7937a1b8b5f91be066dc51ed61be2": false,
|
|
|
|
"8c24f44f1533567c71e722f49bc7a4d9b323a09e2950fd975291817578119508": false,
|
|
|
|
"55a7a738aaee8f7e6d7bcd4c8a38813e57763bff8bfb296418b6cac6d5bfb89a": false,
|
|
|
|
"dfa5f84366cf0b48f1b1e9b24a73557e657f6ac21b676528401f5a630aece571": false,
|
|
|
|
"5839fbcbbca68aef41dfa9a371222565519626affad6be0977d38a82259480a5": false,
|
|
|
|
"6873568cae35e4ce0a7d07ef080ef6eb699b2b9dcbc419fad1c4f645ff8579fc": false,
|
|
|
|
"dbb3c0688003bede7e7bc56d2c9d6362b594512ac686820739d963ef91e2eb9e": false,
|
|
|
|
"3d12353cb8bae8be928131580e960a82f37ca3ad6957ad22c8cadc1b21b2dd1a": false,
|
|
|
|
"8ca87fd5843f000939244151ce027bad5c1f30f1867c7054918b7f9a66b949e8": false,
|
|
|
|
"ad088940e45a73e00a3cdb7f3248c67a3f6e5d1f05d4cfd44c4e1f4d26cfef87": false,
|
|
|
|
"908a398dd65dfd2aad6c06090c5a71d5e5280746577a6ddd5a1f2c1453f71ead": false,
|
|
|
|
}
|
|
|
|
|
2019-10-18 15:38:33 +00:00
|
|
|
var hashes []string
|
2019-08-30 08:29:59 +00:00
|
|
|
|
|
|
|
for _, tx := range b.Transactions {
|
|
|
|
switch tx.Type {
|
|
|
|
case transaction.ContractType:
|
2019-11-27 09:23:18 +00:00
|
|
|
hashes = append(hashes, tx.Hash().StringLE())
|
2019-08-30 08:29:59 +00:00
|
|
|
case transaction.MinerType:
|
2019-11-27 09:23:18 +00:00
|
|
|
hashes = append(hashes, tx.Hash().StringLE())
|
2019-08-30 08:29:59 +00:00
|
|
|
case transaction.ClaimType:
|
2019-11-27 09:23:18 +00:00
|
|
|
hashes = append(hashes, tx.Hash().StringLE())
|
2019-08-30 08:29:59 +00:00
|
|
|
case transaction.InvocationType:
|
2019-11-27 09:23:18 +00:00
|
|
|
hashes = append(hashes, tx.Hash().StringLE())
|
2019-08-30 08:29:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
assert.Equal(t, len(expected), len(hashes))
|
|
|
|
|
|
|
|
// changes value in map to true, if hash found
|
|
|
|
for _, hash := range hashes {
|
|
|
|
expected[hash] = true
|
|
|
|
}
|
|
|
|
|
|
|
|
// iterate map; all vlaues should be true
|
|
|
|
val := true
|
|
|
|
for _, v := range expected {
|
|
|
|
if v == false {
|
|
|
|
val = false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assert.Equal(t, true, val)
|
|
|
|
|
2019-09-16 09:18:13 +00:00
|
|
|
buf := io.NewBufBinWriter()
|
2019-08-30 08:29:59 +00:00
|
|
|
|
2019-09-16 16:31:49 +00:00
|
|
|
b.EncodeBinary(buf.BinWriter)
|
|
|
|
assert.Nil(t, buf.Err)
|
2019-08-30 08:29:59 +00:00
|
|
|
|
|
|
|
assert.Equal(t, rawtx, hex.EncodeToString(buf.Bytes()))
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestBlockSizeCalculation(t *testing.T) {
|
|
|
|
// block taken from mainnet: 0006d3ff96e269f599eb1b5c5a527c218439e498dcc65b63794591bbcdc0516b
|
|
|
|
// The Size in golang is given by counting the number of bytes of an object. (len(Bytes))
|
2019-09-09 08:25:58 +00:00
|
|
|
// its implementation is different from the corresponding C# and python implementations. But the result should
|
2019-08-30 08:29:59 +00:00
|
|
|
// should be the same.In this test we provide more details then necessary because in case of failure we can easily debug the
|
|
|
|
// root cause of the size calculation missmatch.
|
|
|
|
|
|
|
|
rawBlock := "00000000ba33df12e8adbf38b6039e79ee91fdb8b1519e2e6154cb59c0653c81769288f4a22492109b7a84077ed7226c28612eb61428ea9ded9bdc952cdfc13deb4172ef85d1115b0bb62300abff35093d19a14a59e75d652b5d3827bf04c165bbe9ef95cca4bf5501fd45014012afae6df64195041e4764b57caa9e27fc2cfc596833163904136ec95816d104b44b3737d0e9f6b1b4445cd3b6a5cc80f6b0935675bc44dba44415eb309832b3404dc95bcf85e4635556a1d618e4ce947b26972992ed74788df5f9501b850ac0b40b7112d1ff30e4ade00369e16f0d13932d1ba76725e7682db072f8e2cd7752b840d12bb7dd45dd3b0e2098db5c67b6de55b7c40164937491fcaca1239b25860251224ead23ab232add78ccccd347239eae50ffc98f50b2a84c60ec5c3d284647a7406fabf6ca241b759af6b71080c0dfad7395632e989226a7e52f8cd2c133aeb2226e6e1aea47666fd81f578405a9f9bbd9d0bc523c3a44d7a5099ddc649feabe5f406188b8ee478731a89beeb76fdbd108eb0071b8f2b8678f40c5a1f387a491314336783255dee8cc5af4bf914dfeaacecc318fc13e02262658e39e8ce0631941b1f1552102486fd15702c4490a26703112a5cc1d0923fd697a33406bd5a1c00e0013b09a7021024c7b7fb6c310fccf1ba33b082519d82964ea93868d676662d4a59ad548df0e7d2102aaec38470f6aad0042c6e877cfd8087d2676b0f516fddd362801b9bd3936399e2103b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c2103b8d9d5771d8f513aa0869b9cc8d50986403b78c6da36890638c3d46a5adce04a2102ca0e27697b9c248f6f16e085fd0061e26f44da85b58ee835c110caa5ec3ba5542102df48f60e8f3e01c48ff40b9b7f1310d7a8b2a193188befe1c2e3df740e89509357ae140000abff350900000000d101530800e1f5050000000014d8dd86f6d91eb2add2f2d8afeda2184ed94ac33314288017f85d80b889fe02beb5ff203ed9ef538f1653c1087472616e7366657267cf9472821400ceb06ca780c2a937fec5bbec51b900000000000000000220288017f85d80b889fe02beb5ff203ed9ef538f16f0153135323738393433373039313963623362646632650000014140b61b1a8d220c28633fa1a43ef02d334731b16013778664bc28db838d9ab8cfa64f9134fe952ad8a8eb8a6dd9d864055301bcdba4177fd6ee0f52b3f096db2fe4232102bca5c56af0f11e7042f5eaf3d8b2767feb3a8e3ba5668b00e6ea21cb7a215689ac8000000177de54907d16326ff29c3fcd4892afae32043e87ca844929157857093632c4010000019b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc500e9a435000000000849ee84e1f3daaf226589c05de2bf8bcae8c94001414092ba4569663dacd95921318658f8f40662bcff61fdcbbe08da0938a6c93a6d1075b76c86fa5454ca41f762d3b955b8d6755b79ccaf52754169b69e8904f166f8232102e019359f675526fc8505198647e31ed3044ccb0e5cc2ea22fb3bed5420cdf687ac800001ff076e656f2d6f6e6501f3617958f115913192d1de50c8c5ac2c411a4177c7801554d2bf69c27dac86c7010002e72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c606400000000000000915fe29d2d3847bce516f31fcd33f0fb1d90573be72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c6034ed1a0000000000c85c8dca1fbb7473522109cecaf3acac2e27afc60141406a5ad8c2b6e3783184703d22f3bee39a8b0b6f81477bff61833090361cd52ca5160d66215e6044c31aaed44304a28273c65c9ba736cc75341b45fb18995a6c922321039eae6f12690848807983df6accc1b2929de8582e772be6b3ac084a02a576272eacd10187084d3198000000000008660ceb7bc700000014b3a766ac60afa2990d9251db08138fd1facf07ed0800e3598f01000000209b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc514e420bbe1e5bcdfa1b43e97a57380a6cd8fddfd4c56c1096d616b654f6666657267bd097b2fcf70e1fd30a5c3ef51e662feeafeba0100000000000000000120e420bbe1e5bcdfa1b43e97a57380a6cd8fddfd4c01659c1aa6f2f42f7d0548a9680df197d4dda767434490e8bed3e25dbbac5206cd000001e72d286979ee6cb1b7e65dfddfb2e384100b8d148e7758de42e4168b71792c6001000000000000007335f929546270b8f811a0f9427b5712457107e70241400f871fcc8bb58d110ea7b1a4c34390542a925203b147bd68137c9edc79044a657cd5dc00514270d65a77a97c814d1f5090054b6c35f1cde698f765538ccf290c2321023056f0a219758bcd503ff4123a589962003331cb9e14168d649ae7426e3ec26eac4140a4036b311b31e0620fcde6e83ed29e6c7e7fcadf59dcac1ccae352a83608c8117dcd36ca64d5a2ce041b2274481ce65b6d30b463d1ca87a0269177d034ad218d232102a1e6ed9a5cff73ad33b7896465af8e9206eab9c8c75502868b783deb64f232eaacd10179207dcc40f47af5b26c52342d5292eb741b7beaa0d58a9a4a1563441fd0f40c30e1349b7cffdaa674beae0f930ebe6085af9093e5fe56b34a5c220ccdcf6efc336fc5b3a766ac60afa2990d9251db08138fd1facf07ed52c10b63616e63656c4f6666657267bd097b2fcf70e1fd30a5c3ef51e662feeafeba01000000000000000001202e5596a5c23eff8907aa180201c5a6f53c041dd101a9822ade57f6f9b6e999be06961
|
|
|
|
rawBlockBytes, _ := hex.DecodeString(rawBlock)
|
|
|
|
|
|
|
|
b := Block{}
|
|
|
|
|
2019-09-16 09:18:13 +00:00
|
|
|
r := io.NewBinReaderFromBuf(rawBlockBytes)
|
2019-09-16 16:31:49 +00:00
|
|
|
b.DecodeBinary(r)
|
|
|
|
assert.Nil(t, r.Err)
|
2019-08-30 08:29:59 +00:00
|
|
|
|
|
|
|
expected := []struct {
|
|
|
|
ID string
|
|
|
|
Type string
|
|
|
|
Size int
|
|
|
|
Version int
|
|
|
|
InputsLen int
|
|
|
|
OutputsLen int
|
|
|
|
AttributesLen int
|
|
|
|
WitnessesLen int
|
|
|
|
}{ // 20 trans
|
|
|
|
{ID: "f59b04d8e6526684b94b5f8cdbdf691feaff5d45e9aa8e2325a668f1b9130786", Type: "MinerTransaction", Size: 10, Version: 0, InputsLen: 0, OutputsLen: 0, AttributesLen: 0, WitnessesLen: 0},
|
|
|
|
{ID: "7463345f771e70019185d72fa5bd00fbb4f26735daae398ecc6540419332d81e", Type: "InvocationTransaction", Size: 244, Version: 1, InputsLen: 0, OutputsLen: 0, AttributesLen: 2, WitnessesLen: 1},
|
|
|
|
{ID: "cf3aeda21d320ec9b49d322f2b88fea21aa7e9bf243c1e02dfe08f5cc82b74b0", Type: "ContractTransaction", Size: 202, Version: 0, InputsLen: 1, OutputsLen: 1, AttributesLen: 0, WitnessesLen: 1},
|
|
|
|
{ID: "07e502d13ae6255cfabbc9ee2f78a48fc1c43a4f7f713f128342db721bc01af5", Type: "ContractTransaction", Size: 271, Version: 0, InputsLen: 1, OutputsLen: 2, AttributesLen: 1, WitnessesLen: 1},
|
|
|
|
{ID: "0de0baf53136c188bdd179fed9530dfb7dd80697fd59e47ffe294db4f421eb67", Type: "InvocationTransaction", Size: 469, Version: 1, InputsLen: 1, OutputsLen: 1, AttributesLen: 1, WitnessesLen: 2},
|
|
|
|
{ID: "233c8b00ab6a43aafae7fcc2be47fc46493185bb3376160b5809cb745aee3329", Type: "InvocationTransaction", Size: 455, Version: 1, InputsLen: 1, OutputsLen: 1, AttributesLen: 1, WitnessesLen: 2},
|
|
|
|
{ID: "8bf3ae0c692fc830753029fcb6575625ea8181b444cffcbe38404a28b77b3856", Type: "InvocationTransaction", Size: 455, Version: 1, InputsLen: 1, OutputsLen: 1, AttributesLen: 1, WitnessesLen: 2},
|
|
|
|
{ID: "c5285e1460191e1ca7fc07e3c26c5facebb033d56b63b7a41ebf11f2a1cb4306", Type: "InvocationTransaction", Size: 244, Version: 1, InputsLen: 0, OutputsLen: 0, AttributesLen: 2, WitnessesLen: 1},
|
|
|
|
{ID: "dce8b5f6dc093a910e405a230e9b7d546688d411cf960c8a1cc7d386d89b56d6", Type: "ContractTransaction", Size: 202, Version: 0, InputsLen: 1, OutputsLen: 1, AttributesLen: 0, WitnessesLen: 1},
|
|
|
|
{ID: "4cce087cadfa99c2adeaaf1916ada025db124cef8f05d4535b0ad8047ef7d29e", Type: "InvocationTransaction", Size: 455, Version: 1, InputsLen: 1, OutputsLen: 1, AttributesLen: 1, WitnessesLen: 2},
|
|
|
|
{ID: "67df57a20c9d3b2942925f2c66fdc15a21be2c229a22122f6acbdac4dd10bf0a", Type: "InvocationTransaction", Size: 466, Version: 1, InputsLen: 0, OutputsLen: 0, AttributesLen: 4, WitnessesLen: 1},
|
|
|
|
{ID: "ad51030b30e016293caed92781b3bb3f993f86c15ab1153582f658d603fe23db", Type: "InvocationTransaction", Size: 465, Version: 1, InputsLen: 0, OutputsLen: 0, AttributesLen: 4, WitnessesLen: 1},
|
|
|
|
{ID: "1db2d62ad3530f1ae6ca7bd95e766beaff97058681f0e203d8744d7bba065012", Type: "InvocationTransaction", Size: 466, Version: 1, InputsLen: 0, OutputsLen: 0, AttributesLen: 4, WitnessesLen: 1},
|
|
|
|
{ID: "7d7bb6f0db6a71aca85fc9267fa6a59654b00b5f778a39c27214c68f11950f61", Type: "InvocationTransaction", Size: 466, Version: 1, InputsLen: 0, OutputsLen: 0, AttributesLen: 4, WitnessesLen: 1},
|
|
|
|
{ID: "1d534dcf1ce63a9ea9328eab309891ea2a0a5cb11e95cabf22860ee1fb649521", Type: "InvocationTransaction", Size: 466, Version: 1, InputsLen: 0, OutputsLen: 0, AttributesLen: 4, WitnessesLen: 1},
|
|
|
|
{ID: "8f4c9089871a4ad0076b27c061395079e0862f685f27e4bc01b7bac67b0cf8d0", Type: "InvocationTransaction", Size: 455, Version: 1, InputsLen: 1, OutputsLen: 1, AttributesLen: 1, WitnessesLen: 2},
|
|
|
|
{ID: "52b4653fca02e8042092456490036f0b9b18b339f65d9c334e7e9d2b4599f8db", Type: "ContractTransaction", Size: 202, Version: 0, InputsLen: 1, OutputsLen: 1, AttributesLen: 0, WitnessesLen: 1},
|
|
|
|
{ID: "2b4854b1f46c9af0eb06587fd375355adfeea3c8f5921295421251af93d737e1", Type: "ClaimTransaction", Size: 203, Version: 0, InputsLen: 0, OutputsLen: 1, AttributesLen: 0, WitnessesLen: 1},
|
|
|
|
{ID: "61e95e5b14625e897423670dfc3babf021d6b99ca2a73203dd1ac2604a2daadf", Type: "InvocationTransaction", Size: 244, Version: 1, InputsLen: 1, OutputsLen: 1, AttributesLen: 3, WitnessesLen: 1},
|
|
|
|
{ID: "b361dfec8c2cde980b340d2c3ec63cecaea634f91b6d76f24a586aa60fbde483", Type: "InvocationTransaction", Size: 244, Version: 1, InputsLen: 0, OutputsLen: 0, AttributesLen: 2, WitnessesLen: 1},
|
|
|
|
}
|
|
|
|
|
|
|
|
for i, tx := range b.Transactions {
|
|
|
|
txID := tx.Hash()
|
2019-11-27 09:23:18 +00:00
|
|
|
assert.Equal(t, expected[i].ID, txID.StringLE())
|
2019-08-30 08:29:59 +00:00
|
|
|
|
2019-09-16 13:08:00 +00:00
|
|
|
assert.Equal(t, expected[i].Size, io.GetVarSize(tx))
|
2019-08-30 08:29:59 +00:00
|
|
|
assert.Equal(t, expected[i].Type, tx.Type.String())
|
|
|
|
assert.Equal(t, expected[i].Version, int(tx.Version))
|
|
|
|
assert.Equal(t, expected[i].InputsLen, len(tx.Inputs))
|
|
|
|
assert.Equal(t, expected[i].OutputsLen, len(tx.Outputs))
|
|
|
|
assert.Equal(t, expected[i].AttributesLen, len(tx.Attributes))
|
|
|
|
assert.Equal(t, expected[i].WitnessesLen, len(tx.Scripts))
|
|
|
|
}
|
|
|
|
|
|
|
|
assert.Equal(t, len(expected), len(b.Transactions))
|
|
|
|
|
|
|
|
// Block specific tests
|
|
|
|
assert.Equal(t, 0, int(b.Version))
|
2019-11-27 09:23:18 +00:00
|
|
|
assert.Equal(t, "f4889276813c65c059cb54612e9e51b1b8fd91ee799e03b638bfade812df33ba", b.PrevHash.StringLE())
|
|
|
|
assert.Equal(t, "ef7241eb3dc1df2c95dc9bed9dea2814b62e61286c22d77e07847a9b109224a2", b.MerkleRoot.StringLE())
|
2019-08-30 08:29:59 +00:00
|
|
|
assert.Equal(t, 1527894405, int(b.Timestamp))
|
|
|
|
assert.Equal(t, 2340363, int(b.Index))
|
|
|
|
|
2019-12-25 14:34:18 +00:00
|
|
|
nextConsensus := address.Uint160ToString(b.NextConsensus)
|
2019-08-30 08:29:59 +00:00
|
|
|
assert.Equal(t, "APyEx5f4Zm4oCHwFWiSTaph1fPBxZacYVR", nextConsensus)
|
|
|
|
|
|
|
|
assert.Equal(t, "4012afae6df64195041e4764b57caa9e27fc2cfc596833163904136ec95816d104b44b3737d0e9f6b1b4445cd3b6a5cc80f6b0935675bc44dba44415eb309832b3404dc95bcf85e4635556a1d618e4ce947b26972992ed74788df5f9501b850ac0b40b7112d1ff30e4ade00369e16f0d13932d1ba76725e7682db072f8e2cd7752b840d12bb7dd45dd3b0e2098db5c67b6de55b7c40164937491fcaca1239b25860251224ead23ab232add78ccccd347239eae50ffc98f50b2a84c60ec5c3d284647a7406fabf6ca241b759af6b71080c0dfad7395632e989226a7e52f8cd2c133aeb2226e6e1aea47666fd81f578405a9f9bbd9d0bc523c3a44d7a5099ddc649feabe5f406188b8ee478731a89beeb76fdbd108eb0071b8f2b8678f40c5a1f387a491314336783255dee8cc5af4bf914dfeaacecc318fc13e02262658e39e8ce0631941b1", hex.EncodeToString(b.Script.InvocationScript))
|
|
|
|
assert.Equal(t, "552102486fd15702c4490a26703112a5cc1d0923fd697a33406bd5a1c00e0013b09a7021024c7b7fb6c310fccf1ba33b082519d82964ea93868d676662d4a59ad548df0e7d2102aaec38470f6aad0042c6e877cfd8087d2676b0f516fddd362801b9bd3936399e2103b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c2103b8d9d5771d8f513aa0869b9cc8d50986403b78c6da36890638c3d46a5adce04a2102ca0e27697b9c248f6f16e085fd0061e26f44da85b58ee835c110caa5ec3ba5542102df48f60e8f3e01c48ff40b9b7f1310d7a8b2a193188befe1c2e3df740e89509357ae", hex.EncodeToString(b.Script.VerificationScript))
|
2019-11-27 09:23:18 +00:00
|
|
|
assert.Equal(t, "0006d3ff96e269f599eb1b5c5a527c218439e498dcc65b63794591bbcdc0516b", b.Hash().StringLE())
|
2019-08-30 08:29:59 +00:00
|
|
|
|
2019-09-16 09:18:13 +00:00
|
|
|
buf := io.NewBufBinWriter()
|
2019-08-30 08:29:59 +00:00
|
|
|
|
2019-09-16 16:31:49 +00:00
|
|
|
b.EncodeBinary(buf.BinWriter)
|
|
|
|
assert.Nil(t, r.Err)
|
2019-09-16 09:18:13 +00:00
|
|
|
benc := buf.Bytes()
|
2019-08-30 08:29:59 +00:00
|
|
|
// test size of the block
|
2019-09-16 09:18:13 +00:00
|
|
|
assert.Equal(t, 7360, len(benc))
|
|
|
|
assert.Equal(t, rawBlock, hex.EncodeToString(benc))
|
2019-08-30 08:29:59 +00:00
|
|
|
}
|
2019-09-25 16:54:31 +00:00
|
|
|
|
|
|
|
func TestBlockCompare(t *testing.T) {
|
2020-01-15 08:29:50 +00:00
|
|
|
b1 := Block{Base: Base{Index: 1}}
|
|
|
|
b2 := Block{Base: Base{Index: 2}}
|
|
|
|
b3 := Block{Base: Base{Index: 3}}
|
2019-09-25 16:54:31 +00:00
|
|
|
assert.Equal(t, 1, b2.Compare(&b1))
|
|
|
|
assert.Equal(t, 0, b2.Compare(&b2))
|
|
|
|
assert.Equal(t, -1, b2.Compare(&b3))
|
|
|
|
}
|