github.com/deso-protocol/core@v1.2.9/lib/blockchain_test.go (about) 1 package lib 2 3 import ( 4 "encoding/hex" 5 "flag" 6 "fmt" 7 "log" 8 "math/big" 9 "testing" 10 "time" 11 12 chainlib "github.com/btcsuite/btcd/blockchain" 13 "github.com/btcsuite/btcd/btcec" 14 "github.com/dgraph-io/badger/v3" 15 "github.com/golang/glog" 16 "github.com/stretchr/testify/assert" 17 "github.com/stretchr/testify/require" 18 ) 19 20 const ( 21 // go run transaction_util.go --manual_entropy_hex=0,1 22 senderPkString = "tBCKXFJEDSF7Thcc6BUBcB6kicE5qzmLbAtvFf9LfKSXN4LwFt36oX" 23 senderPrivString = "tbc31669t2YuZ2mi1VLtK6a17RXFPdsuBDcenPLc1eU1ZVRHF9Zv4" 24 recipientPkString = "tBCKXU8pf7nkn8M38sYJeAwiBP7HbSJWy9Zmn4sHNL6gA6ahkriymq" 25 recipientPrivString = "tbc24UM432ikvtmyv4zus7HomtUYkxNg3B3HusSLghVxoQXKi9QjZ" 26 27 moneyPkString = "tBCKVUCQ9WxpVmNthS2PKfY1BCxG4GkWvXqDhQ4q3zLtiwKVUNMGYS" 28 moneyPrivString = "tbc2yg6BS7we86H8WUF2xSAmnyJ1x63ZqXaiDkE2mostsxpfmCZiB" 29 30 blockSignerSeed = "essence camp ghost remove document vault ladder swim pupil index apart ring" 31 blockSignerPk = "BC1YLiQ86kwXUy3nfK391xht7N72UmbFY6bGrUsds1A7QKZrs4jJsxo" 32 ) 33 34 func TestProcessBlock(t *testing.T) { 35 assert := assert.New(t) 36 require := require.New(t) 37 _ = assert 38 _ = require 39 40 //hexBytes, _ := hex.DecodeString("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") 41 { 42 hexBytes, err := hex.DecodeString("00000000e9a0b8435a2fc5e19952ceb3a2d5042fb87b6d5f180ea825f3a4cd65") 43 assert.NoError(err) 44 assert.Equal("000000000000000000000000000000000000000000000000000000011883b96c", fmt.Sprintf("%064x", *ExpectedWorkForBlockHash(CopyBytesIntoBlockHash(hexBytes)))) 45 46 } 47 // Satoshi's genesis block hash. 48 { 49 hexBytes, err := hex.DecodeString("000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f") 50 assert.NoError(err) 51 assert.Equal("000000000000000000000000000000000000000000000000000009e8770a5c23", fmt.Sprintf("%064x", *ExpectedWorkForBlockHash(CopyBytesIntoBlockHash(hexBytes)))) 52 } 53 // A more serious block. 54 { 55 56 hexBytes, err := hex.DecodeString("00000000000000000000c4c7bfde307b37ca6e4234d636cdea3e443df2926fff") 57 assert.NoError(err) 58 assert.Equal( 59 "000000000000000000000000000000000000000000014d0aa0d2497b13fcd703", 60 fmt.Sprintf("%064x", *ExpectedWorkForBlockHash(CopyBytesIntoBlockHash(hexBytes)))) 61 } 62 // Some annoying edge cases. 63 { 64 hexBytes, err := hex.DecodeString("0000000000000000000000000000000000000000000000000000000000000000") 65 assert.NoError(err) 66 assert.Equal( 67 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 68 fmt.Sprintf("%064x", *ExpectedWorkForBlockHash(CopyBytesIntoBlockHash(hexBytes)))) 69 } 70 { 71 hexBytes, err := hex.DecodeString("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") 72 assert.NoError(err) 73 assert.Equal( 74 "0000000000000000000000000000000000000000000000000000000000000000", 75 fmt.Sprintf("%064x", *ExpectedWorkForBlockHash(CopyBytesIntoBlockHash(hexBytes)))) 76 } 77 { 78 hexBytes, err := hex.DecodeString("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe") 79 assert.NoError(err) 80 assert.Equal( 81 "0000000000000000000000000000000000000000000000000000000000000001", 82 fmt.Sprintf("%064x", *ExpectedWorkForBlockHash(CopyBytesIntoBlockHash(hexBytes)))) 83 } 84 } 85 86 func _copyBlock(blk *MsgDeSoBlock) *MsgDeSoBlock { 87 data, _ := blk.ToBytes(false) 88 89 testBlock := NewMessage(MsgTypeBlock).(*MsgDeSoBlock) 90 _ = testBlock.FromBytes(data) 91 92 return testBlock 93 } 94 95 func getForkedChain(t *testing.T) (blockA1, blockA2, blockB1, blockB2, 96 blockB3, blockB4, blockB5 *MsgDeSoBlock) { 97 98 assert := assert.New(t) 99 require := require.New(t) 100 _, _ = assert, require 101 102 var err error 103 { 104 chain1, params, _ := NewLowDifficultyBlockchain() 105 mempool1, miner1 := NewTestMiner(t, chain1, params, true /*isSender*/) 106 _ = mempool1 107 108 // Mine two blocks to give the sender some DeSo. 109 blockA1, err = miner1.MineAndProcessSingleBlock(0 /*threadIndex*/, mempool1) 110 require.NoError(err) 111 blockA2, err = miner1.MineAndProcessSingleBlock(0 /*threadIndex*/, mempool1) 112 require.NoError(err) 113 } 114 { 115 chain1, params, _ := NewLowDifficultyBlockchain() 116 mempool1, miner1 := NewTestMiner(t, chain1, params, true /*isSender*/) 117 _ = mempool1 118 119 // Mine two blocks to give the sender some DeSo. 120 blockB1, err = miner1.MineAndProcessSingleBlock(0 /*threadIndex*/, mempool1) 121 require.NoError(err) 122 blockB2, err = miner1.MineAndProcessSingleBlock(0 /*threadIndex*/, mempool1) 123 require.NoError(err) 124 blockB3, err = miner1.MineAndProcessSingleBlock(0 /*threadIndex*/, mempool1) 125 require.NoError(err) 126 blockB4, err = miner1.MineAndProcessSingleBlock(0 /*threadIndex*/, mempool1) 127 require.NoError(err) 128 blockB5, err = miner1.MineAndProcessSingleBlock(0 /*threadIndex*/, mempool1) 129 require.NoError(err) 130 } 131 132 // The variables are set above. 133 return 134 } 135 136 func NewTestBlockchain() (*Blockchain, *DeSoParams, *badger.DB) { 137 db, _ := GetTestBadgerDb() 138 timesource := chainlib.NewMedianTime() 139 140 // Set the number of txns per view regeneration to one while creating the txns 141 ReadOnlyUtxoViewRegenerationIntervalTxns = 1 142 143 // Set some special parameters for testing. If the blocks above are changed 144 // these values should be updated to reflect the latest testnet values. 145 paramsCopy := DeSoTestnetParams 146 147 chain, err := NewBlockchain([]string{blockSignerPk}, 0, ¶msCopy, 148 timesource, db, nil, nil) 149 if err != nil { 150 log.Fatal(err) 151 } 152 153 return chain, ¶msCopy, db 154 } 155 156 func NewLowDifficultyBlockchain() ( 157 *Blockchain, *DeSoParams, *badger.DB) { 158 159 // Set the number of txns per view regeneration to one while creating the txns 160 ReadOnlyUtxoViewRegenerationIntervalTxns = 1 161 162 return NewLowDifficultyBlockchainWithParams(&DeSoTestnetParams) 163 } 164 165 func NewLowDifficultyBlockchainWithParams(params *DeSoParams) ( 166 *Blockchain, *DeSoParams, *badger.DB) { 167 168 // Set the number of txns per view regeneration to one while creating the txns 169 ReadOnlyUtxoViewRegenerationIntervalTxns = 1 170 171 db, _ := GetTestBadgerDb() 172 timesource := chainlib.NewMedianTime() 173 174 // Set some special parameters for testing. If the blocks above are changed 175 // these values should be updated to reflect the latest testnet values. 176 paramsCopy := *params 177 paramsCopy.GenesisBlock = &MsgDeSoBlock{ 178 Header: &MsgDeSoHeader{ 179 Version: 0, 180 PrevBlockHash: mustDecodeHexBlockHash("0000000000000000000000000000000000000000000000000000000000000000"), 181 TransactionMerkleRoot: mustDecodeHexBlockHash("097158f0d27e6d10565c4dc696c784652c3380e0ff8382d3599a4d18b782e965"), 182 TstampSecs: uint64(1560735050), 183 Height: uint64(0), 184 Nonce: uint64(0), 185 // No ExtraNonce is set in the genesis block 186 }, 187 Txns: []*MsgDeSoTxn{ 188 { 189 TxInputs: []*DeSoInput{}, 190 TxOutputs: []*DeSoOutput{}, 191 TxnMeta: &BlockRewardMetadataa{ 192 ExtraData: []byte("They came here, to the new world. World 2.0, version 1776."), 193 }, 194 // A signature is not required for BLOCK_REWARD transactions since they 195 // don't spend anything. 196 }, 197 }, 198 } 199 paramsCopy.MinDifficultyTargetHex = "999999948931e5874cf66a74c0fda790dd8c7458243d400324511a4c71f54faa" 200 paramsCopy.MinChainWorkHex = "0000000000000000000000000000000000000000000000000000000000000000" 201 paramsCopy.MiningIterationsPerCycle = 500 202 // Set maturity to 2 blocks so we can test spending on short chains. The 203 // tests rely on the maturity equaling exactly two blocks (i.e. being 204 // two times the time between blocks). 205 paramsCopy.TimeBetweenBlocks = 2 * time.Second 206 paramsCopy.BlockRewardMaturity = time.Second * 4 207 paramsCopy.TimeBetweenDifficultyRetargets = 100 * time.Second 208 paramsCopy.MaxDifficultyRetargetFactor = 2 209 paramsCopy.SeedBalances = []*DeSoOutput{ 210 { 211 PublicKey: MustBase58CheckDecode(moneyPkString), 212 AmountNanos: uint64(2000000 * NanosPerUnit), 213 }, 214 } 215 216 // Temporarily modify the seed balances to make a specific public 217 // key have some DeSo 218 chain, err := NewBlockchain([]string{blockSignerPk}, 0, 219 ¶msCopy, timesource, db, nil, nil) 220 if err != nil { 221 log.Fatal(err) 222 } 223 224 return chain, ¶msCopy, db 225 } 226 227 func NewTestMiner(t *testing.T, chain *Blockchain, params *DeSoParams, isSender bool) (*DeSoMempool, *DeSoMiner) { 228 assert := assert.New(t) 229 require := require.New(t) 230 _ = assert 231 _ = require 232 233 mempool := NewDeSoMempool( 234 chain, 0, /* rateLimitFeeRateNanosPerKB */ 235 0 /* minFeeRateNanosPerKB */, "", true, 236 "" /*dataDir*/, "") 237 minerPubKeys := []string{} 238 if isSender { 239 minerPubKeys = append(minerPubKeys, senderPkString) 240 } else { 241 minerPubKeys = append(minerPubKeys, recipientPkString) 242 } 243 244 blockProducer, err := NewDeSoBlockProducer( 245 0, 1, 246 blockSignerSeed, 247 mempool, chain, 248 params, nil) 249 require.NoError(err) 250 251 newMiner, err := NewDeSoMiner(minerPubKeys, 1 /*numThreads*/, blockProducer, params) 252 require.NoError(err) 253 return mempool, newMiner 254 } 255 256 func _getBalance(t *testing.T, chain *Blockchain, mempool *DeSoMempool, pkStr string) uint64 { 257 pkBytes, _, err := Base58CheckDecode(pkStr) 258 require.NoError(t, err) 259 260 utxoEntriesFound, err := chain.GetSpendableUtxosForPublicKey(pkBytes, mempool, nil) 261 require.NoError(t, err) 262 263 balanceForUserNanos := uint64(0) 264 for _, utxoEntry := range utxoEntriesFound { 265 balanceForUserNanos += utxoEntry.AmountNanos 266 } 267 268 utxoView, err := NewUtxoView(chain.db, chain.params, nil) 269 require.NoError(t, err) 270 if mempool != nil { 271 utxoView, err = mempool.GetAugmentedUniversalView() 272 require.NoError(t, err) 273 } 274 275 balanceNanos, err := utxoView.GetSpendableDeSoBalanceNanosForPublicKey( 276 pkBytes, chain.headerTip().Height) 277 require.NoError(t, err) 278 279 // DO NOT REMOVE: This is used to test the similarity of UTXOs vs. the pubkey balance index. 280 require.Equal(t, balanceForUserNanos, balanceNanos) 281 282 return balanceForUserNanos 283 } 284 285 func _getCreatorCoinInfo(t *testing.T, db *badger.DB, params *DeSoParams, pkStr string, 286 ) (_desoLocked uint64, _coinsInCirculation uint64) { 287 pkBytes, _, err := Base58CheckDecode(pkStr) 288 require.NoError(t, err) 289 290 utxoView, _ := NewUtxoView(db, params, nil) 291 292 // Profile fields 293 creatorProfile := utxoView.GetProfileEntryForPublicKey(pkBytes) 294 if creatorProfile == nil { 295 return 0, 0 296 } 297 298 return creatorProfile.DeSoLockedNanos, creatorProfile.CoinsInCirculationNanos 299 } 300 301 func _getBalanceWithView(t *testing.T, utxoView *UtxoView, pkStr string) uint64 { 302 pkBytes, _, err := Base58CheckDecode(pkStr) 303 require.NoError(t, err) 304 305 utxoEntriesFound, err := utxoView.GetUnspentUtxoEntrysForPublicKey(pkBytes) 306 require.NoError(t, err) 307 308 totalBalanceNanos := uint64(0) 309 for _, utxoEntry := range utxoEntriesFound { 310 totalBalanceNanos += utxoEntry.AmountNanos 311 } 312 313 return totalBalanceNanos 314 } 315 316 func TestBasicTransferReorg(t *testing.T) { 317 assert := assert.New(t) 318 require := require.New(t) 319 _ = assert 320 _ = require 321 322 chain1, params, _ := NewLowDifficultyBlockchain() 323 { 324 mempool1, miner1 := NewTestMiner(t, chain1, params, true /*isSender*/) 325 326 // Mine two blocks to give the sender some DeSo. 327 _, err := miner1.MineAndProcessSingleBlock(0 /*threadIndex*/, mempool1) 328 require.NoError(err) 329 _, err = miner1.MineAndProcessSingleBlock(0 /*threadIndex*/, mempool1) 330 require.NoError(err) 331 332 // Have the sender send some DeSo to the recipient and have the 333 // recipient send some back. Mine both of these transactions into 334 // a block. 335 { 336 txn := _assembleBasicTransferTxnFullySigned(t, chain1, 17, 0, 337 senderPkString, recipientPkString, senderPrivString, mempool1) 338 _, err := mempool1.ProcessTransaction(txn, false /*allowUnconnectedTxn*/, false /*rateLimit*/, 0 /*peerID*/, true /*verifySignatures*/) 339 require.NoError(err) 340 } 341 { 342 txn := _assembleBasicTransferTxnFullySigned(t, chain1, 4, 0, 343 recipientPkString, senderPkString, recipientPrivString, mempool1) 344 _, err := mempool1.ProcessTransaction(txn, false /*allowUnconnectedTxn*/, false /*rateLimit*/, 0 /*peerID*/, true /*verifySignatures*/) 345 require.NoError(err) 346 } 347 block, err := miner1.MineAndProcessSingleBlock(0 /*threadIndex*/, mempool1) 348 require.NoError(err) 349 // block reward adds one txn. 350 require.Equal(3, len(block.Txns)) 351 require.Equal(uint64(13), _getBalance(t, chain1, mempool1, recipientPkString)) 352 353 // Have the sender send a bit more DeSo over and mine that into a 354 // block. 355 { 356 txn := _assembleBasicTransferTxnFullySigned(t, chain1, 2, 0, 357 senderPkString, recipientPkString, senderPrivString, mempool1) 358 _, err := mempool1.ProcessTransaction(txn, false /*allowUnconnectedTxn*/, false /*rateLimit*/, 0 /*peerID*/, true /*verifySignatures*/) 359 require.NoError(err) 360 } 361 block, err = miner1.MineAndProcessSingleBlock(0 /*threadIndex*/, mempool1) 362 require.NoError(err) 363 // block reward adds one txn. 364 require.Equal(2, len(block.Txns)) 365 require.Equal(uint64(15), _getBalance(t, chain1, mempool1, recipientPkString)) 366 367 // A transaction signed by the wrong private key should be rejected. 368 { 369 txn := _assembleBasicTransferTxnFullySigned(t, chain1, 2, 0, 370 senderPkString, recipientPkString, recipientPrivString, mempool1) 371 _, err := mempool1.ProcessTransaction(txn, false /*allowUnconnectedTxn*/, false /*rateLimit*/, 0 /*peerID*/, true /*verifySignatures*/) 372 require.Error(err) 373 require.Contains(err.Error(), RuleErrorInvalidTransactionSignature) 374 } 375 376 // Have the recipient send some DeSo back and mine that into a block. 377 { 378 txn := _assembleBasicTransferTxnFullySigned(t, chain1, 8, 0, 379 recipientPkString, senderPkString, recipientPrivString, mempool1) 380 _, err := mempool1.ProcessTransaction(txn, false /*allowUnconnectedTxn*/, false /*rateLimit*/, 0 /*peerID*/, true /*verifySignatures*/) 381 require.NoError(err) 382 } 383 block, err = miner1.MineAndProcessSingleBlock(0 /*threadIndex*/, mempool1) 384 require.NoError(err) 385 // block reward adds one txn. 386 require.Equal(2, len(block.Txns)) 387 388 // Recipient should have exactly 7 DeSo after all this. 389 require.Equal(uint64(7), _getBalance(t, chain1, mempool1, recipientPkString)) 390 } 391 392 // Create a second test chain so we can mine a fork. 393 // Mine enough blocks to create a fork. Throw in a transaction 394 // from the sender to the recipient right before the third block 395 // just to make things interesting. 396 chain2, _, _ := NewLowDifficultyBlockchain() 397 forkBlocks := []*MsgDeSoBlock{} 398 { 399 mempool2, miner2 := NewTestMiner(t, chain2, params, true /*isSender*/) 400 401 // Mine two blocks to give the sender some DeSo. 402 block, err := miner2.MineAndProcessSingleBlock(0 /*threadIndex*/, mempool2) 403 require.NoError(err) 404 forkBlocks = append(forkBlocks, block) 405 block, err = miner2.MineAndProcessSingleBlock(0 /*threadIndex*/, mempool2) 406 require.NoError(err) 407 forkBlocks = append(forkBlocks, block) 408 409 // Have the sender send some DeSo to the recipient and have the 410 // recipient send some back. Mine both of these transactions into 411 // a block. 412 { 413 txn := _assembleBasicTransferTxnFullySigned(t, chain2, 7, 0, 414 senderPkString, recipientPkString, senderPrivString, mempool2) 415 _, err := mempool2.ProcessTransaction(txn, false /*allowUnconnectedTxn*/, false /*rateLimit*/, 0 /*peerID*/, true /*verifySignatures*/) 416 require.NoError(err) 417 } 418 { 419 txn := _assembleBasicTransferTxnFullySigned(t, chain2, 2, 0, 420 recipientPkString, senderPkString, recipientPrivString, mempool2) 421 _, err := mempool2.ProcessTransaction(txn, false /*allowUnconnectedTxn*/, false /*rateLimit*/, 0 /*peerID*/, true /*verifySignatures*/) 422 require.NoError(err) 423 } 424 block, err = miner2.MineAndProcessSingleBlock(0 /*threadIndex*/, mempool2) 425 require.NoError(err) 426 forkBlocks = append(forkBlocks, block) 427 // block reward adds one txn. 428 require.Equal(3, len(block.Txns)) 429 require.Equal(uint64(5), _getBalance(t, chain2, mempool2, recipientPkString)) 430 431 // Mine several more blocks so we can make the fork dominant. 432 block, err = miner2.MineAndProcessSingleBlock(0 /*threadIndex*/, mempool2) 433 require.NoError(err) 434 forkBlocks = append(forkBlocks, block) 435 block, err = miner2.MineAndProcessSingleBlock(0 /*threadIndex*/, mempool2) 436 require.NoError(err) 437 forkBlocks = append(forkBlocks, block) 438 block, err = miner2.MineAndProcessSingleBlock(0 /*threadIndex*/, mempool2) 439 require.NoError(err) 440 forkBlocks = append(forkBlocks, block) 441 block, err = miner2.MineAndProcessSingleBlock(0 /*threadIndex*/, mempool2) 442 require.NoError(err) 443 forkBlocks = append(forkBlocks, block) 444 block, err = miner2.MineAndProcessSingleBlock(0 /*threadIndex*/, mempool2) 445 require.NoError(err) 446 forkBlocks = append(forkBlocks, block) 447 } 448 449 // Process all of the fork blocks on the original chain to make it 450 // experience a reorg. 451 for _, forkBlock := range forkBlocks { 452 _, _, err := chain1.ProcessBlock(forkBlock, true /*verifySignatures*/) 453 require.NoError(err) 454 } 455 456 // Require that the tip of the first chain is now the same as the last 457 // fork block. 458 lastForkBlockHash, _ := forkBlocks[len(forkBlocks)-1].Hash() 459 require.Equal(*lastForkBlockHash, *chain1.blockTip().Hash) 460 461 // After the reorg, all of the transactions should have been undone 462 // expcept the single spend from the sender to the recipient that 463 /// occurred in the fork. As such the fork chain's balance should now 464 // reflect the updated balance. 465 require.Equal(uint64(5), _getBalance(t, chain1, nil, recipientPkString)) 466 } 467 468 func TestProcessBlockConnectBlocks(t *testing.T) { 469 assert := assert.New(t) 470 require := require.New(t) 471 _, _ = assert, require 472 473 var blockA1 *MsgDeSoBlock 474 { 475 chain1, params, _ := NewLowDifficultyBlockchain() 476 mempool1, miner1 := NewTestMiner(t, chain1, params, true /*isSender*/) 477 _ = mempool1 478 479 // Mine two blocks to give the sender some DeSo. 480 var err error 481 blockA1, err = miner1.MineAndProcessSingleBlock(0 /*threadIndex*/, mempool1) 482 require.NoError(err) 483 } 484 485 chain, _, _ := NewLowDifficultyBlockchain() 486 _shouldConnectBlock(blockA1, t, chain) 487 } 488 489 func _shouldConnectBlock(blk *MsgDeSoBlock, t *testing.T, chain *Blockchain) { 490 require := require.New(t) 491 492 blockHash, _ := blk.Hash() 493 494 verifySignatures := true 495 isMainChain, isOrphan, err := chain.ProcessBlock(blk, verifySignatures) 496 require.NoError(err) 497 require.Falsef(isOrphan, "Block %v should not be an orphan", blockHash) 498 require.Truef(isMainChain, "Block %v should be on the main chain", blockHash) 499 500 // The header tip and the block tip should now be equal to this block. 501 require.Equal(*blockHash, *chain.headerTip().Hash) 502 require.Equal(*blockHash, *chain.blockTip().Hash) 503 } 504 505 func TestSeedBalancesTest(t *testing.T) { 506 assert, require := assert.New(t), require.New(t) 507 _, _ = assert, require 508 509 chain, params, db := NewTestBlockchain() 510 for _, seedBalance := range params.SeedBalances { 511 require.Equal(int64(482), int64(GetUtxoNumEntries(db))) 512 foundUtxos, err := chain.GetSpendableUtxosForPublicKey(seedBalance.PublicKey, nil, nil) 513 require.NoError(err) 514 require.Equal(int64(1), int64(len(foundUtxos))) 515 require.Equal(int64(seedBalance.AmountNanos), int64(foundUtxos[0].AmountNanos)) 516 } 517 } 518 519 func init() { 520 // Set up logging. 521 flag.Set("alsologtostderr", "true") 522 glog.CopyStandardLogTo("INFO") 523 } 524 525 func TestProcessHeaderskReorgBlocks(t *testing.T) { 526 assert := assert.New(t) 527 require := require.New(t) 528 _, _ = assert, require 529 530 blockA1, blockA2, blockB1, blockB2, blockB3, _, _ := getForkedChain(t) 531 532 chain, _, db := NewLowDifficultyBlockchain() 533 534 { 535 // These should connect without issue. 536 fmt.Println("Connecting header A1") 537 // We should start with one UTXO since there's a founder reward. 538 require.Equal(uint64(1), GetUtxoNumEntries(db)) 539 headerHash, err := blockA1.Header.Hash() 540 require.NoError(err) 541 isMainChain, isOrphan, err := chain.ProcessHeader(blockA1.Header, headerHash) 542 require.NoError(err) 543 require.True(isMainChain) 544 require.False(isOrphan) 545 // Make sure the tip lines up. 546 currentHash, err := blockA1.Hash() 547 require.NoError(err) 548 require.Equal(*currentHash, *(chain.headerTip().Hash)) 549 } 550 { 551 // These should connect without issue. 552 fmt.Println("Connecting header A2") 553 // We should start with one UTXO since there's a founder reward. 554 require.Equal(uint64(1), GetUtxoNumEntries(db)) 555 headerHash, err := blockA2.Header.Hash() 556 require.NoError(err) 557 isMainChain, isOrphan, err := chain.ProcessHeader(blockA2.Header, headerHash) 558 require.NoError(err) 559 require.True(isMainChain) 560 require.False(isOrphan) 561 // Make sure the tip lines up. 562 currentHash, err := blockA2.Hash() 563 require.NoError(err) 564 require.Equal(*currentHash, *(chain.headerTip().Hash)) 565 } 566 { 567 // These should connect without issue. 568 fmt.Println("Connecting header B1") 569 // We should start with one UTXO since there's a founder reward. 570 require.Equal(uint64(1), GetUtxoNumEntries(db)) 571 headerHash, err := blockB1.Header.Hash() 572 require.NoError(err) 573 isMainChain, isOrphan, err := chain.ProcessHeader(blockB1.Header, headerHash) 574 require.NoError(err) 575 // Should not be main chain yet 576 require.False(isMainChain) 577 require.False(isOrphan) 578 // Make sure the tip lines up. 579 currentHash, err := blockA2.Hash() 580 require.NoError(err) 581 require.Equal(*currentHash, *(chain.headerTip().Hash)) 582 } 583 { 584 // These should connect without issue. 585 fmt.Println("Connecting header B2") 586 // We should start with one UTXO since there's a founder reward. 587 require.Equal(uint64(1), GetUtxoNumEntries(db)) 588 headerHash, err := blockB2.Header.Hash() 589 require.NoError(err) 590 isMainChain, isOrphan, err := chain.ProcessHeader(blockB2.Header, headerHash) 591 require.NoError(err) 592 // Should not be main chain yet 593 require.False(isMainChain) 594 require.False(isOrphan) 595 // Make sure the tip lines up. 596 currentHash, err := blockA2.Hash() 597 require.NoError(err) 598 require.Equal(*currentHash, *(chain.headerTip().Hash)) 599 } 600 { 601 // These should connect without issue. 602 fmt.Println("Connecting header B3") 603 // We should start with one UTXO since there's a founder reward. 604 require.Equal(uint64(1), GetUtxoNumEntries(db)) 605 headerHash, err := blockB3.Header.Hash() 606 require.NoError(err) 607 isMainChain, isOrphan, err := chain.ProcessHeader(blockB3.Header, headerHash) 608 require.NoError(err) 609 // Should not be main chain yet 610 require.True(isMainChain) 611 require.False(isOrphan) 612 // Make sure the tip lines up. 613 currentHash, err := blockB3.Hash() 614 require.NoError(err) 615 require.Equal(*currentHash, *(chain.headerTip().Hash)) 616 } 617 } 618 619 func TestProcessBlockReorgBlocks(t *testing.T) { 620 assert := assert.New(t) 621 require := require.New(t) 622 _, _ = assert, require 623 624 blockA1, blockA2, blockB1, blockB2, blockB3, _, _ := getForkedChain(t) 625 626 chain, _, db := NewLowDifficultyBlockchain() 627 628 { 629 // These should connect without issue. 630 fmt.Println("Connecting block a1") 631 // We should start with one UTXO since there's a founder reward. 632 require.Equal(uint64(1), GetUtxoNumEntries(db)) 633 _shouldConnectBlock(blockA1, t, chain) 634 635 // Make sure the tip lines up. 636 currentHash, err := blockA1.Hash() 637 require.NoError(err) 638 require.Equal(*currentHash, *(chain.headerTip().Hash)) 639 require.Equal(*currentHash, *(chain.blockTip().Hash)) 640 } 641 642 { 643 fmt.Println("Connecting block a2") 644 require.Equal(uint64(2), GetUtxoNumEntries(db)) 645 _shouldConnectBlock(blockA2, t, chain) 646 647 // Make sure the tip lines up. 648 currentHash, err := blockA2.Hash() 649 require.NoError(err) 650 require.Equal(*currentHash, *(chain.headerTip().Hash)) 651 require.Equal(*currentHash, *(chain.blockTip().Hash)) 652 } 653 654 verifySignatures := true 655 { 656 // These should not be on the main chain. 657 // Block b1 658 fmt.Println("Connecting block b1") 659 require.Equal(uint64(3), GetUtxoNumEntries(db)) 660 isMainChain, isOrphan, err := chain.ProcessBlock(blockB1, verifySignatures) 661 require.NoError(err) 662 require.Falsef(isOrphan, "Block b1 should not be an orphan") 663 require.Falsef(isMainChain, "Block b1 should not be on the main chain") 664 665 // Make sure the tip lines up. 666 currentHash, err := blockA2.Hash() 667 require.NoError(err) 668 require.Equal(*currentHash, *(chain.headerTip().Hash)) 669 require.Equal(*currentHash, *(chain.blockTip().Hash)) 670 } 671 672 { 673 // Block b2 674 fmt.Println("Connecting block b2") 675 require.Equal(uint64(3), GetUtxoNumEntries(db)) 676 isMainChain, isOrphan, err := chain.ProcessBlock(blockB2, verifySignatures) 677 require.NoError(err) 678 require.Falsef(isOrphan, "Block b2 should not be an orphan") 679 require.Falsef(isMainChain, "Block b2 should not be on the main chain") 680 681 // Make sure the tip lines up. 682 currentHash, err := blockA2.Hash() 683 require.NoError(err) 684 require.Equal(*currentHash, *(chain.headerTip().Hash)) 685 require.Equal(*currentHash, *(chain.blockTip().Hash)) 686 } 687 688 { 689 // This should cause the fork to take over, changing the main chain. 690 fmt.Println("Connecting block b3") 691 require.Equal(uint64(3), GetUtxoNumEntries(db)) 692 _shouldConnectBlock(blockB3, t, chain) 693 fmt.Println("b3 is connected") 694 require.Equal(uint64(4), GetUtxoNumEntries(db)) 695 696 // Make sure the tip lines up. 697 currentHash, err := blockB3.Hash() 698 require.NoError(err) 699 require.Equal(*currentHash, *(chain.headerTip().Hash)) 700 require.Equal(*currentHash, *(chain.blockTip().Hash)) 701 } 702 } 703 704 func _assembleBasicTransferTxnNoInputs(t *testing.T, amountNanos uint64) *MsgDeSoTxn { 705 require := require.New(t) 706 707 // manual_entropy_hex=0 708 senderPkBytes, _, err := Base58CheckDecode(senderPkString) 709 require.NoError(err) 710 711 // manual_entropy_hex=1 712 recipientPkBytes, _, err := Base58CheckDecode(recipientPkString) 713 require.NoError(err) 714 715 // Assemble the transaction so that inputs can be found and fees can 716 // be computed. 717 txnOutputs := []*DeSoOutput{} 718 txnOutputs = append(txnOutputs, &DeSoOutput{ 719 PublicKey: recipientPkBytes, 720 AmountNanos: amountNanos, 721 }) 722 txn := &MsgDeSoTxn{ 723 // The inputs will be set below. 724 TxInputs: []*DeSoInput{}, 725 TxOutputs: txnOutputs, 726 PublicKey: senderPkBytes, 727 TxnMeta: &BasicTransferMetadata{}, 728 // We wait to compute the signature until we've added all the 729 // inputs and change. 730 } 731 732 return txn 733 } 734 735 func _signTxn(t *testing.T, txn *MsgDeSoTxn, privKeyStrArg string) { 736 require := require.New(t) 737 738 privKeyBytes, _, err := Base58CheckDecode(privKeyStrArg) 739 require.NoError(err) 740 privKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), privKeyBytes) 741 txnSignature, err := txn.Sign(privKey) 742 require.NoError(err) 743 txn.Signature = txnSignature 744 } 745 746 // Signs the transaction with a derived key. Transaction ExtraData contains the derived 747 // public key, so that _verifySignature() knows transaction wasn't signed by the owner. 748 func _signTxnWithDerivedKey(t *testing.T, txn *MsgDeSoTxn, privKeyStrArg string) { 749 require := require.New(t) 750 751 privKeyBytes, _, err := Base58CheckDecode(privKeyStrArg) 752 require.NoError(err) 753 privateKey, publicKey := btcec.PrivKeyFromBytes(btcec.S256(), privKeyBytes) 754 if txn.ExtraData == nil { 755 txn.ExtraData = make(map[string][]byte) 756 } 757 txn.ExtraData[DerivedPublicKey] = publicKey.SerializeCompressed() 758 txnSignature, err := txn.Sign(privateKey) 759 require.NoError(err) 760 761 txn.Signature = txnSignature 762 } 763 764 func _assembleBasicTransferTxnFullySigned(t *testing.T, chain *Blockchain, 765 amountNanos uint64, feeRateNanosPerKB uint64, senderPkStrArg string, 766 recipientPkStrArg string, privKeyStrArg string, 767 mempool *DeSoMempool) *MsgDeSoTxn { 768 769 require := require.New(t) 770 771 // go run transaction_util.go --operation_type=generate_keys --manual_entropy_hex=0 772 senderPkBytes, _, err := Base58CheckDecode(senderPkStrArg) 773 require.NoError(err) 774 775 // go run transaction_util.go --operation_type=generate_keys --manual_entropy_hex=1 776 recipientPkBytes, _, err := Base58CheckDecode(recipientPkStrArg) 777 require.NoError(err) 778 779 // Assemble the transaction so that inputs can be found and fees can 780 // be computed. 781 txnOutputs := []*DeSoOutput{} 782 txnOutputs = append(txnOutputs, &DeSoOutput{ 783 PublicKey: recipientPkBytes, 784 AmountNanos: amountNanos, 785 }) 786 txn := &MsgDeSoTxn{ 787 // The inputs will be set below. 788 TxInputs: []*DeSoInput{}, 789 TxOutputs: txnOutputs, 790 PublicKey: senderPkBytes, 791 TxnMeta: &BasicTransferMetadata{}, 792 // We wait to compute the signature until we've added all the 793 // inputs and change. 794 } 795 796 totalInputAdded, spendAmount, totalChangeAdded, fee, err := 797 chain.AddInputsAndChangeToTransaction(txn, feeRateNanosPerKB, mempool) 798 require.NoError(err) 799 require.Equal(totalInputAdded, spendAmount+totalChangeAdded+fee) 800 801 _signTxn(t, txn, privKeyStrArg) 802 803 return txn 804 } 805 806 func TestAddInputsAndChangeToTransaction(t *testing.T) { 807 assert := assert.New(t) 808 require := require.New(t) 809 _ = assert 810 _ = require 811 812 chain, _, db := NewLowDifficultyBlockchain() 813 _ = db 814 815 _, _, blockB1, blockB2, blockB3, _, _ := getForkedChain(t) 816 817 // Spending nothing should be OK. It shouldn't add anything to the transaction. 818 { 819 txn := _assembleBasicTransferTxnNoInputs(t, 0) 820 feeRateNanosPerKB := uint64(0) 821 822 totalInputAdded, spendAmount, totalChangeAdded, fee, err := 823 chain.AddInputsAndChangeToTransaction(txn, feeRateNanosPerKB, nil) 824 require.NoError(err) 825 require.Equal(0, len(txn.TxInputs)) 826 require.Equal(1, len(txn.TxOutputs)) 827 require.Equal(totalInputAdded, uint64(0)) 828 require.Equal(spendAmount, uint64(0)) 829 require.Equal(totalChangeAdded, uint64(0)) 830 require.Equal(fee, uint64(0)) 831 } 832 833 // Spending a nonzero amount should fail before we have mined a block 834 // reward for ourselves. 835 { 836 txn := _assembleBasicTransferTxnNoInputs(t, 1) 837 feeRateNanosPerKB := uint64(0) 838 839 _, _, _, _, err := 840 chain.AddInputsAndChangeToTransaction(txn, feeRateNanosPerKB, nil) 841 require.Error(err) 842 } 843 844 // Nonzero/high fee should also cause an error if we have no money. 845 { 846 txn := _assembleBasicTransferTxnNoInputs(t, 0) 847 feeRateNanosPerKB := uint64(1000) 848 849 _, _, _, _, err := 850 chain.AddInputsAndChangeToTransaction(txn, feeRateNanosPerKB, nil) 851 require.Error(err) 852 } 853 854 // Save the block reward in the first block to use it for testing. 855 firstBlockReward := CalcBlockRewardNanos(1) 856 857 // Connect a block. The sender address should have mined some DeSo but 858 // it should be unspendable until the block after this one. See 859 // BlockRewardMaturity. 860 _shouldConnectBlock(blockB1, t, chain) 861 862 // Verify that spending a nonzero amount fails after the first block. 863 { 864 txn := _assembleBasicTransferTxnNoInputs(t, 1) 865 feeRateNanosPerKB := uint64(0) 866 867 _, _, _, _, err := 868 chain.AddInputsAndChangeToTransaction(txn, feeRateNanosPerKB, nil) 869 require.Error(err) 870 } 871 872 _shouldConnectBlock(blockB2, t, chain) 873 874 // Verify that spending a nonzero amount passes after the second block 875 // since at this point it is presumed the transaction will be mined 876 // into the third block at which point the block reward shouild be 877 // mature. 878 879 // Verify a moderate spend with a moderate feerate works. 880 { 881 testSpend := firstBlockReward / 2 882 txn := _assembleBasicTransferTxnNoInputs(t, testSpend) 883 feeRateNanosPerKB := uint64(testSpend) 884 885 totalInputAdded, spendAmount, totalChangeAdded, fee, err := 886 chain.AddInputsAndChangeToTransaction(txn, feeRateNanosPerKB, nil) 887 require.NoError(err) 888 require.Equal(1, len(txn.TxInputs)) 889 require.Equal(2, len(txn.TxOutputs)) 890 require.Equal(spendAmount, uint64(testSpend)) 891 require.Greater(fee, uint64(0)) 892 require.Equal(uint64(firstBlockReward), totalInputAdded) 893 require.Equal(totalInputAdded, spendAmount+totalChangeAdded+fee) 894 } 895 896 // Verify spending more than a block reward fails. 897 { 898 testSpend := firstBlockReward + 1 899 txn := _assembleBasicTransferTxnNoInputs(t, testSpend) 900 feeRateNanosPerKB := uint64(0) 901 902 _, _, _, _, err := 903 chain.AddInputsAndChangeToTransaction(txn, feeRateNanosPerKB, nil) 904 require.Error(err) 905 } 906 907 _shouldConnectBlock(blockB3, t, chain) 908 909 // Verify spending more than the first block reward passes after the 910 // next block. 911 { 912 testSpend := firstBlockReward + 1 913 txn := _assembleBasicTransferTxnNoInputs(t, testSpend) 914 feeRateNanosPerKB := uint64(0) 915 916 _, _, _, _, err := 917 chain.AddInputsAndChangeToTransaction(txn, feeRateNanosPerKB, nil) 918 require.NoError(err) 919 } 920 } 921 922 func TestValidateBasicTransfer(t *testing.T) { 923 assert := assert.New(t) 924 require := require.New(t) 925 _ = assert 926 _ = require 927 928 chain, _, db := NewLowDifficultyBlockchain() 929 _ = db 930 931 _, _, blockB1, blockB2, _, _, _ := getForkedChain(t) 932 933 // Save the block reward in the first block to use it for testing. 934 firstBlockReward := CalcBlockRewardNanos(1) 935 936 // Connect a block. The sender address should have mined some DeSo but 937 // it should be unspendable until the block after this one. See 938 // BlockRewardMaturity. 939 _shouldConnectBlock(blockB1, t, chain) 940 _shouldConnectBlock(blockB2, t, chain) 941 942 // Verify that a transaction spending a nonzero amount passes validation 943 // after the second block due to the block reward having matured. 944 { 945 spendAmount := firstBlockReward / 2 946 feeRateNanosPerKB := firstBlockReward 947 txn := _assembleBasicTransferTxnFullySigned(t, chain, spendAmount, feeRateNanosPerKB, 948 senderPkString, recipientPkString, senderPrivString, nil) 949 err := chain.ValidateTransaction(txn, chain.blockTip().Height+1, 950 true /*verifySignatures*/, nil) 951 require.NoError(err) 952 } 953 954 // Verify that a transaction spending more than its input is shot down. 955 { 956 spendAmount := firstBlockReward / 2 957 feeRateNanosPerKB := firstBlockReward 958 txn := _assembleBasicTransferTxnFullySigned(t, chain, spendAmount, feeRateNanosPerKB, 959 senderPkString, recipientPkString, senderPrivString, nil) 960 { 961 senderPkBytes, _, err := Base58CheckDecode(senderPkString) 962 require.NoError(err) 963 txn.TxOutputs = append(txn.TxOutputs, &DeSoOutput{ 964 PublicKey: senderPkBytes, 965 // Guaranteed to be more than we're allowed to spend. 966 AmountNanos: firstBlockReward, 967 }) 968 // Re-sign the transaction. 969 _signTxn(t, txn, senderPrivString) 970 } 971 972 err := chain.ValidateTransaction(txn, chain.blockTip().Height+1, true, nil) 973 require.Error(err) 974 require.Contains(err.Error(), RuleErrorTxnOutputExceedsInput) 975 } 976 977 // Verify that a transaction spending an immature block reward is shot down. 978 { 979 spendAmount := firstBlockReward 980 feeRateNanosPerKB := uint64(0) 981 txn := _assembleBasicTransferTxnFullySigned(t, chain, spendAmount, feeRateNanosPerKB, 982 senderPkString, recipientPkString, senderPrivString, nil) 983 // Try and spend the block reward from block B2, which should not have matured 984 // yet. 985 b2RewardHash := blockB2.Txns[0].Hash() 986 require.NotNil(b2RewardHash) 987 txn.TxInputs = append(txn.TxInputs, &DeSoInput{ 988 TxID: *b2RewardHash, 989 Index: 0, 990 }) 991 // Re-sign the transaction. 992 _signTxn(t, txn, senderPrivString) 993 err := chain.ValidateTransaction(txn, chain.blockTip().Height+1, true, nil) 994 require.Error(err) 995 require.Contains(err.Error(), RuleErrorInputSpendsImmatureBlockReward) 996 } 997 } 998 999 func TestComputeMerkle(t *testing.T) { 1000 //assert := assert.New(t) 1001 //require := require.New(t) 1002 //_ = assert 1003 //_ = require 1004 1005 //blk := _copyBlock(expectedBlock) 1006 //merkleRoot1, _, err := ComputeMerkleRoot(blk.Txns) 1007 //require.NoError(err) 1008 1009 //blk.Header.Nonce[0] = 0x00 1010 //merkleRoot2, _, err := ComputeMerkleRoot(blk.Txns) 1011 //require.NoError(err) 1012 //assert.Equal(merkleRoot1, merkleRoot2) 1013 1014 //oldSigVal := blk.Txns[1].Signature[5] 1015 //blk.Txns[1].Signature[5] = 0x00 1016 //merkleRoot3, _, err := ComputeMerkleRoot(blk.Txns) 1017 //require.NoError(err) 1018 //assert.NotEqual(merkleRoot1, merkleRoot3) 1019 1020 //blk.Txns[1].Signature[5] = oldSigVal 1021 //merkleRoot4, _, err := ComputeMerkleRoot(blk.Txns) 1022 //require.NoError(err) 1023 //assert.Equal(merkleRoot1, merkleRoot4) 1024 } 1025 1026 func TestCalcNextDifficultyTargetHalvingDoublingHitLimit(t *testing.T) { 1027 assert := assert.New(t) 1028 require := require.New(t) 1029 _ = assert 1030 _ = require 1031 1032 fakeParams := &DeSoParams{ 1033 MinDifficultyTargetHex: hex.EncodeToString(BigintToHash(big.NewInt(100000))[:]), 1034 TimeBetweenDifficultyRetargets: 6 * time.Second, 1035 TimeBetweenBlocks: 2 * time.Second, 1036 MaxDifficultyRetargetFactor: 2, 1037 } 1038 1039 nodes := []*BlockNode{} 1040 diffsAsInts := []int64{} 1041 for ii := 0; ii < 13; ii++ { 1042 var lastNode *BlockNode 1043 if ii > 0 { 1044 lastNode = nodes[ii-1] 1045 } 1046 nextDiff, err := CalcNextDifficultyTarget(lastNode, HeaderVersion0, fakeParams) 1047 require.NoErrorf(err, "Block index: %d", ii) 1048 nodes = append(nodes, NewBlockNode( 1049 lastNode, 1050 nil, 1051 uint32(ii), 1052 nextDiff, 1053 nil, 1054 &MsgDeSoHeader{ 1055 // Blocks generating every 1 second, which is 2x too fast. 1056 TstampSecs: uint64(ii), 1057 }, 1058 StatusNone, 1059 )) 1060 1061 diffsAsInts = append(diffsAsInts, HashToBigint(nextDiff).Int64()) 1062 } 1063 1064 assert.Equal([]int64{ 1065 100000, 1066 100000, 1067 100000, 1068 100000, 1069 100000, 1070 100000, 1071 100000, 1072 50000, 1073 50000, 1074 50000, 1075 25000, 1076 25000, 1077 25000, 1078 }, diffsAsInts) 1079 1080 diffsAsInts = []int64{} 1081 for ii := 13; ii < 30; ii++ { 1082 lastNode := nodes[ii-1] 1083 nextDiff, err := CalcNextDifficultyTarget(lastNode, HeaderVersion0, fakeParams) 1084 require.NoErrorf(err, "Block index: %d", ii) 1085 nodes = append(nodes, NewBlockNode( 1086 lastNode, 1087 nil, 1088 uint32(ii), 1089 nextDiff, 1090 nil, 1091 &MsgDeSoHeader{ 1092 // Blocks generating every 4 second, which is 2x too slow. 1093 TstampSecs: uint64(ii * 4), 1094 }, 1095 StatusNone, 1096 )) 1097 1098 diffsAsInts = append(diffsAsInts, HashToBigint(nextDiff).Int64()) 1099 } 1100 1101 assert.Equal([]int64{ 1102 12500, 1103 12500, 1104 12500, 1105 25000, 1106 25000, 1107 25000, 1108 50000, 1109 50000, 1110 50000, 1111 100000, 1112 100000, 1113 100000, 1114 100000, 1115 100000, 1116 100000, 1117 100000, 1118 100000, 1119 }, diffsAsInts) 1120 } 1121 1122 func TestCalcNextDifficultyTargetHittingLimitsSlow(t *testing.T) { 1123 assert := assert.New(t) 1124 require := require.New(t) 1125 _ = assert 1126 _ = require 1127 1128 fakeParams := &DeSoParams{ 1129 MinDifficultyTargetHex: hex.EncodeToString(BigintToHash(big.NewInt(100000))[:]), 1130 TimeBetweenDifficultyRetargets: 6 * time.Second, 1131 TimeBetweenBlocks: 2 * time.Second, 1132 MaxDifficultyRetargetFactor: 2, 1133 } 1134 1135 nodes := []*BlockNode{} 1136 diffsAsInts := []int64{} 1137 for ii := 0; ii < 13; ii++ { 1138 var lastNode *BlockNode 1139 if ii > 0 { 1140 lastNode = nodes[ii-1] 1141 } 1142 nextDiff, err := CalcNextDifficultyTarget(lastNode, HeaderVersion0, fakeParams) 1143 require.NoErrorf(err, "Block index: %d", ii) 1144 nodes = append(nodes, NewBlockNode( 1145 lastNode, 1146 nil, 1147 uint32(ii), 1148 nextDiff, 1149 nil, 1150 &MsgDeSoHeader{ 1151 // Blocks generating every 1 second, which is 2x too fast. 1152 TstampSecs: uint64(ii), 1153 }, 1154 StatusNone, 1155 )) 1156 1157 diffsAsInts = append(diffsAsInts, HashToBigint(nextDiff).Int64()) 1158 } 1159 1160 assert.Equal([]int64{ 1161 100000, 1162 100000, 1163 100000, 1164 100000, 1165 100000, 1166 100000, 1167 100000, 1168 50000, 1169 50000, 1170 50000, 1171 25000, 1172 25000, 1173 25000, 1174 }, diffsAsInts) 1175 1176 diffsAsInts = []int64{} 1177 for ii := 13; ii < 30; ii++ { 1178 lastNode := nodes[ii-1] 1179 nextDiff, err := CalcNextDifficultyTarget(lastNode, HeaderVersion0, fakeParams) 1180 require.NoErrorf(err, "Block index: %d", ii) 1181 nodes = append(nodes, NewBlockNode( 1182 lastNode, 1183 nil, 1184 uint32(ii), 1185 nextDiff, 1186 nil, 1187 &MsgDeSoHeader{ 1188 // Blocks generating every 8 second, which is >2x too slow. 1189 TstampSecs: uint64(ii * 4), 1190 }, 1191 StatusNone, 1192 )) 1193 1194 diffsAsInts = append(diffsAsInts, HashToBigint(nextDiff).Int64()) 1195 } 1196 1197 assert.Equal([]int64{ 1198 12500, 1199 12500, 1200 12500, 1201 25000, 1202 25000, 1203 25000, 1204 50000, 1205 50000, 1206 50000, 1207 100000, 1208 100000, 1209 100000, 1210 100000, 1211 100000, 1212 100000, 1213 100000, 1214 100000, 1215 }, diffsAsInts) 1216 } 1217 1218 func TestCalcNextDifficultyTargetHittingLimitsFast(t *testing.T) { 1219 assert := assert.New(t) 1220 require := require.New(t) 1221 _ = assert 1222 _ = require 1223 1224 fakeParams := &DeSoParams{ 1225 MinDifficultyTargetHex: hex.EncodeToString(BigintToHash(big.NewInt(100000))[:]), 1226 TimeBetweenDifficultyRetargets: 6 * time.Second, 1227 TimeBetweenBlocks: 2 * time.Second, 1228 MaxDifficultyRetargetFactor: 2, 1229 } 1230 1231 nodes := []*BlockNode{} 1232 diffsAsInts := []int64{} 1233 for ii := 0; ii < 13; ii++ { 1234 var lastNode *BlockNode 1235 if ii > 0 { 1236 lastNode = nodes[ii-1] 1237 } 1238 nextDiff, err := CalcNextDifficultyTarget(lastNode, HeaderVersion0, fakeParams) 1239 require.NoErrorf(err, "Block index: %d", ii) 1240 nodes = append(nodes, NewBlockNode( 1241 lastNode, 1242 nil, 1243 uint32(ii), 1244 nextDiff, 1245 nil, 1246 &MsgDeSoHeader{ 1247 // Blocks generating all at once. 1248 TstampSecs: uint64(0), 1249 }, 1250 StatusNone, 1251 )) 1252 1253 diffsAsInts = append(diffsAsInts, HashToBigint(nextDiff).Int64()) 1254 } 1255 1256 assert.Equal([]int64{ 1257 100000, 1258 100000, 1259 100000, 1260 100000, 1261 100000, 1262 100000, 1263 100000, 1264 50000, 1265 50000, 1266 50000, 1267 25000, 1268 25000, 1269 25000, 1270 }, diffsAsInts) 1271 } 1272 1273 func TestCalcNextDifficultyTargetJustRight(t *testing.T) { 1274 assert := assert.New(t) 1275 require := require.New(t) 1276 _ = assert 1277 _ = require 1278 1279 fakeParams := &DeSoParams{ 1280 MinDifficultyTargetHex: hex.EncodeToString(BigintToHash(big.NewInt(100000))[:]), 1281 TimeBetweenDifficultyRetargets: 6 * time.Second, 1282 TimeBetweenBlocks: 2 * time.Second, 1283 MaxDifficultyRetargetFactor: 3, 1284 } 1285 1286 nodes := []*BlockNode{} 1287 diffsAsInts := []int64{} 1288 for ii := 0; ii < 13; ii++ { 1289 var lastNode *BlockNode 1290 if ii > 0 { 1291 lastNode = nodes[ii-1] 1292 } 1293 nextDiff, err := CalcNextDifficultyTarget(lastNode, HeaderVersion0, fakeParams) 1294 require.NoErrorf(err, "Block index: %d", ii) 1295 nodes = append(nodes, NewBlockNode( 1296 lastNode, 1297 nil, 1298 uint32(ii), 1299 nextDiff, 1300 nil, 1301 &MsgDeSoHeader{ 1302 // Blocks generating every 2 second, which is under the limit. 1303 TstampSecs: uint64(ii * 2), 1304 }, 1305 StatusNone, 1306 )) 1307 1308 diffsAsInts = append(diffsAsInts, HashToBigint(nextDiff).Int64()) 1309 } 1310 1311 assert.Equal([]int64{ 1312 100000, 1313 100000, 1314 100000, 1315 100000, 1316 100000, 1317 100000, 1318 100000, 1319 100000, 1320 100000, 1321 100000, 1322 100000, 1323 100000, 1324 100000, 1325 }, diffsAsInts) 1326 } 1327 1328 func TestCalcNextDifficultyTargetSlightlyOff(t *testing.T) { 1329 assert := assert.New(t) 1330 require := require.New(t) 1331 _ = assert 1332 _ = require 1333 1334 fakeParams := &DeSoParams{ 1335 MinDifficultyTargetHex: hex.EncodeToString(BigintToHash(big.NewInt(100000))[:]), 1336 TimeBetweenDifficultyRetargets: 6 * time.Second, 1337 TimeBetweenBlocks: 2 * time.Second, 1338 MaxDifficultyRetargetFactor: 2, 1339 } 1340 1341 nodes := []*BlockNode{} 1342 diffsAsInts := []int64{} 1343 for ii := 0; ii < 13; ii++ { 1344 var lastNode *BlockNode 1345 if ii > 0 { 1346 lastNode = nodes[ii-1] 1347 } 1348 nextDiff, err := CalcNextDifficultyTarget(lastNode, HeaderVersion0, fakeParams) 1349 require.NoErrorf(err, "Block index: %d", ii) 1350 nodes = append(nodes, NewBlockNode( 1351 lastNode, 1352 nil, 1353 uint32(ii), 1354 nextDiff, 1355 nil, 1356 &MsgDeSoHeader{ 1357 // Blocks generating every 1 second, which is 2x too fast. 1358 TstampSecs: uint64(ii), 1359 }, 1360 StatusNone, 1361 )) 1362 1363 diffsAsInts = append(diffsAsInts, HashToBigint(nextDiff).Int64()) 1364 } 1365 1366 assert.Equal([]int64{ 1367 100000, 1368 100000, 1369 100000, 1370 100000, 1371 100000, 1372 100000, 1373 100000, 1374 50000, 1375 50000, 1376 50000, 1377 25000, 1378 25000, 1379 25000, 1380 }, diffsAsInts) 1381 1382 diffsAsInts = []int64{} 1383 for ii := 13; ii < 34; ii++ { 1384 lastNode := nodes[ii-1] 1385 nextDiff, err := CalcNextDifficultyTarget(lastNode, HeaderVersion0, fakeParams) 1386 require.NoErrorf(err, "Block index: %d", ii) 1387 nodes = append(nodes, NewBlockNode( 1388 lastNode, 1389 nil, 1390 uint32(ii), 1391 nextDiff, 1392 nil, 1393 &MsgDeSoHeader{ 1394 // Blocks generating every 3 seconds, which is slow but under the limit. 1395 TstampSecs: uint64(float32(ii) * 3), 1396 }, 1397 StatusNone, 1398 )) 1399 1400 diffsAsInts = append(diffsAsInts, HashToBigint(nextDiff).Int64()) 1401 } 1402 1403 assert.Equal([]int64{ 1404 12500, 1405 12500, 1406 12500, 1407 25000, 1408 25000, 1409 25000, 1410 37500, 1411 37500, 1412 37500, 1413 56250, 1414 56250, 1415 56250, 1416 84375, 1417 84375, 1418 84375, 1419 100000, 1420 100000, 1421 100000, 1422 100000, 1423 100000, 1424 100000, 1425 }, diffsAsInts) 1426 } 1427 1428 func _testMerkleRoot(t *testing.T, shouldFail bool, blk *MsgDeSoBlock) { 1429 assert := assert.New(t) 1430 require := require.New(t) 1431 _, _ = assert, require 1432 1433 computedMerkle, _, err := ComputeMerkleRoot(blk.Txns) 1434 require.NoError(err) 1435 if shouldFail { 1436 require.NotEqual(blk.Header.TransactionMerkleRoot, computedMerkle) 1437 } else { 1438 require.Equal(blk.Header.TransactionMerkleRoot, computedMerkle) 1439 } 1440 } 1441 1442 func TestBadMerkleRoot(t *testing.T) { 1443 assert := assert.New(t) 1444 require := require.New(t) 1445 _, _ = assert, require 1446 1447 // Grab some block hex by running miner.go at v=2 and use test_scratch.go 1448 // to perturb the merkle root to mess it up. 1449 blockA1, _, _, _, _, _, _ := getForkedChain(t) 1450 _testMerkleRoot(t, false /*shouldFail*/, blockA1) 1451 blockA1.Header.TransactionMerkleRoot = &BlockHash{} 1452 _testMerkleRoot(t, true /*shouldFail*/, blockA1) 1453 } 1454 1455 func TestBadBlockSignature(t *testing.T) { 1456 assert := assert.New(t) 1457 require := require.New(t) 1458 _, _ = assert, require 1459 1460 chain, params, db := NewLowDifficultyBlockchainWithParams(&DeSoTestnetParams) 1461 1462 // Change the trusted public keys expected by the blockchain. 1463 chain.trustedBlockProducerPublicKeys = make(map[PkMapKey]bool) 1464 senderPkBytes, _, err := Base58CheckDecode(senderPkString) 1465 require.NoError(err) 1466 chain.trustedBlockProducerPublicKeys[MakePkMapKey(senderPkBytes)] = true 1467 1468 // The "blockSignerPk" does not match "senderPk" so processing the block will fail. 1469 mempool, miner := NewTestMiner(t, chain, params, true /*isSender*/) 1470 finalBlock1, err := miner.MineAndProcessSingleBlock(0 /*threadIndex*/, mempool) 1471 require.Error(err) 1472 require.Contains(err.Error(), RuleErrorBlockProducerPublicKeyNotInWhitelist) 1473 1474 // Since MineAndProcesssSingleBlock returns a valid block above, we can play with its 1475 // signature and re-process the block to see what happens. 1476 blockProducerInfoCopy := &BlockProducerInfo{Signature: &btcec.Signature{}} 1477 blockProducerInfoCopy.PublicKey = append([]byte{}, finalBlock1.BlockProducerInfo.PublicKey...) 1478 *blockProducerInfoCopy.Signature = *finalBlock1.BlockProducerInfo.Signature 1479 1480 // A bad signature with the right public key should fail. 1481 finalBlock1.BlockProducerInfo.PublicKey = senderPkBytes 1482 _, _, err = chain.ProcessBlock(finalBlock1, true) 1483 require.Error(err) 1484 require.Contains(err.Error(), RuleErrorInvalidBlockProducerSIgnature) 1485 1486 // A signature that's outright missing should fail 1487 blockSignerPkBytes, _, err := Base58CheckDecode(blockSignerPk) 1488 require.NoError(err) 1489 finalBlock1.BlockProducerInfo.PublicKey = blockSignerPkBytes 1490 finalBlock1.BlockProducerInfo.Signature = nil 1491 _, _, err = chain.ProcessBlock(finalBlock1, true) 1492 require.Error(err) 1493 require.Contains(err.Error(), RuleErrorMissingBlockProducerSignature) 1494 1495 // If all the BlockProducerInfo is missing, things should fail 1496 finalBlock1.BlockProducerInfo = nil 1497 _, _, err = chain.ProcessBlock(finalBlock1, true) 1498 require.Error(err) 1499 require.Contains(err.Error(), RuleErrorMissingBlockProducerSignature) 1500 1501 // Now let's add blockSignerPK to the map of trusted keys and confirm that the block processes. 1502 chain.trustedBlockProducerPublicKeys[MakePkMapKey(blockSignerPkBytes)] = true 1503 finalBlock1.BlockProducerInfo = blockProducerInfoCopy 1504 _, _, err = chain.ProcessBlock(finalBlock1, true) 1505 require.NoError(err) 1506 1507 _, _ = finalBlock1, db 1508 } 1509 1510 func TestForbiddenBlockSignaturePubKey(t *testing.T) { 1511 assert := assert.New(t) 1512 require := require.New(t) 1513 _, _ = assert, require 1514 1515 chain, params, _ := NewLowDifficultyBlockchainWithParams(&DeSoTestnetParams) 1516 mempool, miner := NewTestMiner(t, chain, params, true /*isSender*/) 1517 1518 // Make the senderPk a paramUpdater for this test 1519 senderPkBytes, _, err := Base58CheckDecode(senderPkString) 1520 params.ParamUpdaterPublicKeys[MakePkMapKey(senderPkBytes)] = true 1521 1522 // Mine a few blocks to give the senderPkString some money. 1523 _, err = miner.MineAndProcessSingleBlock(0 /*threadIndex*/, mempool) 1524 require.NoError(err) 1525 _, err = miner.MineAndProcessSingleBlock(0 /*threadIndex*/, mempool) 1526 require.NoError(err) 1527 _, err = miner.MineAndProcessSingleBlock(0 /*threadIndex*/, mempool) 1528 require.NoError(err) 1529 _, err = miner.MineAndProcessSingleBlock(0 /*threadIndex*/, mempool) 1530 require.NoError(err) 1531 1532 // Ban the block signer public key. 1533 blockSignerPkBytes, _, err := Base58CheckDecode(blockSignerPk) 1534 require.NoError(err) 1535 txn, _, _, _, err := chain.CreateUpdateGlobalParamsTxn( 1536 senderPkBytes, -1, -1, -1, -1, -1, blockSignerPkBytes, 100 /*feeRateNanosPerKB*/, nil, []*DeSoOutput{}) 1537 require.NoError(err) 1538 1539 // Mine a few blocks to give the senderPkString some money. 1540 _, err = miner.MineAndProcessSingleBlock(0 /*threadIndex*/, mempool) 1541 require.NoError(err) 1542 1543 // Sign the transaction now that its inputs are set up. 1544 _signTxn(t, txn, senderPrivString) 1545 1546 // Process the signed transaction. 1547 txDescsAdded, err := mempool.processTransaction( 1548 txn, true /*allowOrphan*/, true /*rateLimit*/, 0, /*peerID*/ 1549 true /*verifySignatures*/) 1550 require.NoError(err) 1551 require.Equal(1, len(txDescsAdded)) 1552 1553 // Make sure that the forbidden pub key made it into the mempool properly. 1554 _, entryExists := mempool.universalUtxoView.ForbiddenPubKeyToForbiddenPubKeyEntry[MakePkMapKey(blockSignerPkBytes)] 1555 require.True(entryExists) 1556 1557 // Mine the transaction. 1558 forbiddenPubKeyBlock, err := miner.MineAndProcessSingleBlock(0 /*threadIndex*/, mempool) 1559 require.NoError(err) 1560 require.Equal(2, len(forbiddenPubKeyBlock.Txns)) 1561 1562 // Now mining a block should fail now that the block signer pub key is forbidden. 1563 _, err = miner.MineAndProcessSingleBlock(0 /*threadIndex*/, mempool) 1564 require.Error(err) 1565 require.Contains(err.Error(), RuleErrorForbiddenBlockProducerPublicKey) 1566 }