github.com/aergoio/aergo@v1.3.1/types/blockchain_test.go (about) 1 package types 2 3 import ( 4 "fmt" 5 "math" 6 "math/big" 7 "testing" 8 "time" 9 10 "github.com/golang/protobuf/proto" 11 "github.com/minio/sha256-simd" 12 13 "github.com/libp2p/go-libp2p-core/crypto" 14 "github.com/stretchr/testify/assert" 15 ) 16 17 func TestBlockHash(t *testing.T) { 18 blockHash := func(block *Block) []byte { 19 header := block.Header 20 digest := sha256.New() 21 writeBlockHeaderOld(digest, header) 22 return digest.Sum(nil) 23 } 24 25 txIn := make([]*Tx, 0) 26 block := NewBlock(nil, nil, nil, txIn, nil, 0) 27 28 h1 := blockHash(block) 29 h2 := block.calculateBlockHash() 30 31 assert.Equal(t, h1, h2) 32 } 33 34 func genKeyPair(assert *assert.Assertions) (crypto.PrivKey, crypto.PubKey) { 35 privKey, pubKey, err := crypto.GenerateKeyPair(crypto.Secp256k1, 256) 36 assert.Nil(err) 37 38 return privKey, pubKey 39 } 40 41 func genSign(assert *assert.Assertions, block *Block, privKey crypto.PrivKey) []byte { 42 msg, err := block.Header.bytesForDigest() 43 assert.Nil(err) 44 45 sig, err := privKey.Sign(msg) 46 assert.Nil(err) 47 48 return sig 49 } 50 51 func TestBlockSignBasic(t *testing.T) { 52 signAssert := assert.New(t) 53 54 message := func(block *Block) []byte { 55 msg, err := block.Header.bytesForDigest() 56 signAssert.Nil(err) 57 58 return msg 59 } 60 61 sign := func(block *Block, privKey crypto.PrivKey) []byte { 62 sig, err := privKey.Sign(message(block)) 63 signAssert.Nil(err) 64 65 return sig 66 } 67 68 verify := func(block *Block, sig []byte, pubKey crypto.PubKey) bool { 69 valid, err := pubKey.Verify(message(block), sig) 70 signAssert.Nil(err) 71 72 return valid 73 } 74 75 block := NewBlock(nil, nil, nil, make([]*Tx, 0), nil, 0) 76 77 privKey, pubKey := genKeyPair(signAssert) 78 sig := sign(block, privKey) 79 valid := verify(block, sig, pubKey) 80 signAssert.True(valid) 81 } 82 83 func TestBlockSign(t *testing.T) { 84 signAssert := assert.New(t) 85 block := NewBlock(nil, nil, nil, make([]*Tx, 0), nil, 0) 86 87 privKey, _ := genKeyPair(signAssert) 88 signAssert.Nil(block.Sign(privKey)) 89 90 sig := genSign(signAssert, block, privKey) 91 signAssert.NotNil(sig) 92 93 signAssert.Equal(sig, block.Header.Sign) 94 95 valid, err := block.VerifySign() 96 signAssert.Nil(err) 97 signAssert.True(valid) 98 } 99 100 func TestMovingAverage(t *testing.T) { 101 size := int64(10) 102 mv := NewMovingAverage(int(size)) 103 104 assert.Equal(t, int64(0), mv.calculateAvg()) 105 106 var sum = int64(0) 107 var expAvg int64 108 for i := int64(1); i <= size; i++ { 109 avg := mv.Add(int64(i)) 110 assert.Equal(t, i, int64(mv.count)) 111 112 sum += i 113 expAvg = sum / i 114 assert.Equal(t, expAvg, avg) 115 } 116 117 for i := int64(size + 1); i <= (size + 10); i++ { 118 avg := mv.Add(int64(i)) 119 assert.Equal(t, size, int64(mv.count)) 120 121 sum = sum + i - (i - size) 122 expAvg = sum / size 123 assert.Equal(t, expAvg, avg) 124 } 125 } 126 127 func TestUpdateAvgVerifyTime(t *testing.T) { 128 var size = int64(10) 129 avgTime := NewAvgTime(int(size)) 130 131 val := avgTime.Get() 132 133 assert.Equal(t, int64(0), int64(val)) 134 135 var sum = int64(0) 136 var expAvg int64 137 138 for i := int64(1); i <= size; i++ { 139 avgTime.UpdateAverage(time.Duration(i)) 140 newAvg := avgTime.Get() 141 142 sum += i 143 expAvg = sum / i 144 assert.Equal(t, expAvg, int64(newAvg)) 145 } 146 147 for i := int64(size + 1); i <= (size + 10); i++ { 148 avgTime.UpdateAverage(time.Duration(i)) 149 newAvg := avgTime.Get() 150 151 sum = sum + i - (i - size) 152 expAvg = sum / size 153 assert.Equal(t, expAvg, int64(newAvg)) 154 } 155 } 156 157 func TestBlockLimit(t *testing.T) { 158 a := assert.New(t) 159 160 chainID := "0123456789012345678901234567890123456789" 161 dig := sha256.New() 162 dig.Write([]byte(chainID)) 163 h := dig.Sum(nil) 164 165 addr, err := DecodeAddress("AmLquXjQSiDdR8FTDK78LJ16Ycrq3uNL6NQuiwqXRCGw9Riq2DE4") 166 a.Nil(err, "invalid coinbase account") 167 168 _, pub := genKeyPair(a) 169 170 block := &Block{ 171 Header: &BlockHeader{ 172 ChainID: []byte(chainID), // len <= 40 173 PrevBlockHash: h, // 32byte 174 BlockNo: math.MaxUint64, 175 Timestamp: math.MinInt64, 176 BlocksRootHash: h, // 32byte. Currenly not used but for the future use. 177 TxsRootHash: h, // 32byte 178 ReceiptsRootHash: h, // 32byte 179 Confirms: math.MaxUint64, 180 CoinbaseAccount: addr, 181 }, 182 Body: &BlockBody{Txs: make([]*Tx, 0)}, 183 } 184 err = block.setPubKey(pub) 185 a.Nil(err, "PubKey set failed") 186 187 // The signature's max length is 72 (strict DER format). But usually it is 188 // 70 or 71. For header length measurement, generate a byte array of length 189 // 72 from a hash (sha256) value xrather than a real signature. 190 block.Header.Sign = h 191 block.Header.Sign = append(block.Header.Sign, h...) 192 block.Header.Sign = append(block.Header.Sign, h[:8]...) 193 194 // A block can include its sha256 hash value. Thus the size of blcok hash 195 // value should be considered when the block header limit estimated. 196 fmt.Println("block id:", block.ID()) 197 198 hdrSize := proto.Size(block) 199 a.True(hdrSize <= DefaultMaxHdrSize, "too large header (> %v): %v", DefaultMaxHdrSize, hdrSize) 200 201 fmt.Println("hdr size", hdrSize) 202 203 const testSender = "AmPNYHyzyh9zweLwDyuoiUuTVCdrdksxkRWDjVJS76WQLExa2Jr4" 204 account, _ := DecodeAddress(testSender) 205 amount, ok := new(big.Int).SetString("999999999999999999", 10) 206 a.True(ok, "amount conversion failed") 207 208 //blk := &Block{} 209 tx := &Tx{ 210 Body: &TxBody{ 211 Nonce: math.MaxUint64, 212 Account: account, 213 Recipient: account, 214 Amount: amount.Bytes(), 215 Payload: []byte(`{"Name":"v1unstake"}`), 216 GasLimit: math.MaxUint64, 217 GasPrice: amount.Bytes(), 218 Sign: block.GetHeader().GetSign(), 219 Type: TxType_GOVERNANCE, 220 }, 221 } 222 tx.Hash = tx.CalculateTxHash() 223 224 txSize := proto.Size(tx) 225 226 nTx := 10000 227 var i int 228 229 hdrLimit := 400 230 bodyLimit := 1000000 231 limit := hdrLimit + bodyLimit 232 s := 0 233 for i = 1; i <= nTx; i++ { 234 if s += proto.Size(tx); s > bodyLimit { 235 break 236 } 237 block.Body.Txs = append(block.Body.Txs, tx) 238 } 239 240 fmt.Println("estimate #1: ", block.Size(), "esimate #2: ", txSize*i+hdrSize, "actual: ", proto.Size(block)) 241 a.True(block.Size() <= proto.Size(block), "block size violation") 242 a.True(block.Size() <= txSize*i+hdrSize, "block size violation") 243 a.True(block.Size() <= limit, "block size violation") 244 }