func TestGetNextBlock(t *testing.T) { transactions, _ := fixtureSampleTransactions(t) blk, err := block.NewBlock(types.EmptyHash(), block.HIGHEST_TARGET, transactions) if err != nil { t.Errorf("can't create a block because of %v", err) } blk1, err := block.NewBlock(blk.Hash(), block.HIGHEST_TARGET, []*transaction.Envelope{}) if err != nil { t.Errorf("can't create a block because of %v", err) } db, err := NewDB("test.db") defer os.Remove("test.db") if err != nil { t.Errorf("error opening database: %v", err) } err = db.PutBlock(blk, false) if err != nil { t.Errorf("error putting block: %v", err) } blk_, err := db.GetNextBlock(types.EmptyHash()) if err != nil { t.Errorf("error getting next block: %v", err) } assert.Equal(t, blk, blk_) err = db.PutBlock(blk1, false) if err != nil { t.Errorf("error putting block: %v", err) } blk1_, err := db.GetNextBlock(blk.Hash()) if err != nil { t.Errorf("error getting next block: %v", err) } assert.Equal(t, blk1_, blk1) block0, err := db.GetBlock(types.EmptyHash()) if err == nil { t.Errorf("error getting zero block (no error thrown)") } if block0 != nil { t.Errorf("error getting zero block") } assert.True(t, nil == block0) }
func TestGetTransactionBlock(t *testing.T) { transactions := fixtureSampleTransactions(t) block, err := block.NewBlock(types.EmptyHash(), block.HIGHEST_TARGET, transactions) if err != nil { t.Errorf("can't create a block because of %v", err) } db, err := NewDB("test.db") defer os.Remove("test.db") if err != nil { t.Errorf("error opening database: %v", err) } err = db.PutBlock(block, false) if err != nil { t.Errorf("error putting block: %v", err) } // Block<->transaction indexing for i := range transactions { block1, err := db.GetTransactionBlock(transactions[i].Hash()) if err != nil { t.Errorf("error getting transaction's block: %v", err) } assert.Equal(t, block, block1) } }
func TestTransactionConfirmations(t *testing.T) { db, err := NewDB("test.db") defer os.Remove("test.db") if err != nil { t.Errorf("error opening database: %v", err) } transactions := fixtureSampleTransactions(t) confirmationsTest := func(count int, note string) { for i := range transactions { confirmations, err := db.GetTransactionConfirmations(transactions[i].Hash()) if err != nil { t.Errorf("error getting transaction's confirmations: %v", err) } assert.Equal(t, confirmations, count, note) } } blk, err := block.NewBlock(types.EmptyHash(), block.HIGHEST_TARGET, transactions) if err != nil { t.Errorf("can't create a block because of %v", err) } confirmationsTest(0, "no transaction was confirmed yet") err = db.PutBlock(blk, true) if err != nil { t.Errorf("error putting block: %v", err) } confirmationsTest(1, "there should be one confirmation") anotherSampleOfTransactions := fixtureSampleTransactions(t) blk, err = block.NewBlock(blk.Hash(), block.HIGHEST_TARGET, anotherSampleOfTransactions) err = db.PutBlock(blk, true) if err != nil { t.Errorf("error putting block: %v", err) } }
func TestPutGetBlock(t *testing.T) { privateKey := generateECDSAKey(t) txn1, rand := transaction.NewNameReservation("my-new-repository", &privateKey.PublicKey) txn2, _ := transaction.NewNameAllocation("my-new-repository", rand, privateKey) txn3, _ := transaction.NewNameDeallocation("my-new-repository", privateKey) transactions := []transaction.T{txn1, txn2, txn3} block, err := block.NewBlock(types.EmptyHash(), block.HIGHEST_TARGET, transactions) if err != nil { t.Errorf("can't create a block because of %v", err) } db, err := NewDB("test.db") defer os.Remove("test.db") if err != nil { t.Errorf("error opening database: %v", err) } err = db.PutBlock(block, false) if err != nil { t.Errorf("error putting block: %v", err) } block1, err := db.GetBlock(block.Hash()) if err != nil { t.Errorf("error getting block: %v", err) } if block1 == nil { t.Errorf("error getting block %v", block.Hash()) } assert.Equal(t, block, block1) // Attempt fetching the last one block1, err = db.GetLastBlock() if err != nil { t.Errorf("error getting block: %v", err) } if block1 != nil { t.Errorf("error getting block, there should be no last block") } // Set the last one err = db.PutBlock(block, true) if err != nil { t.Errorf("error putting block: %v", err) } block1, err = db.GetLastBlock() if err != nil { t.Errorf("error getting last block: %v", err) } if block1 == nil { t.Errorf("error getting block, there should be a last block") } assert.Equal(t, block, block1) }
func TestPutGetBlock(t *testing.T) { transactions, _ := fixtureSampleTransactions(t) blk, err := block.NewBlock(types.EmptyHash(), block.HIGHEST_TARGET, transactions) if err != nil { t.Errorf("can't create a block because of %v", err) } db, err := NewDB("test.db") defer os.Remove("test.db") if err != nil { t.Errorf("error opening database: %v", err) } err = db.PutBlock(blk, false) if err != nil { t.Errorf("error putting block: %v", err) } block1, err := db.GetBlock(blk.Hash()) if err != nil { t.Errorf("error getting block: %v", err) } if block1 == nil { t.Errorf("error getting block %v", blk.Hash()) } assert.Equal(t, blk, block1) // Attempt fetching the last one block1, err = db.GetLastBlock() if err != nil { t.Errorf("error getting block: %v", err) } if block1 != nil { t.Errorf("error getting block, there should be no last block") } // Set the last one err = db.PutBlock(blk, true) if err != nil { t.Errorf("error putting block: %v", err) } block1, err = db.GetLastBlock() if err != nil { t.Errorf("error getting last block: %v", err) } if block1 == nil { t.Errorf("error getting block, there should be a last block") } assert.Equal(t, blk, block1) }
func mineBlock(status MiningStatus, srv *context.T, log log15.Logger, previousBlockHash types.Hash, transactions []*transaction.Envelope) { if bat := prepareBAT(srv, log); bat != nil { blk, err := block.NewBlock(previousBlockHash, targetBits(), append(transactions, bat)) if err != nil { log.Error("error while creating a new block", "err", err) } else { // send off the new pool for i := range status.Miners { status.Miners[i].signallingChannel <- blk status.Miners[i].Block = blk status.Miners[i].StartTime = time.Now() } } } }
func TestGetPreviousEnvelopeHashForPublicKey(t *testing.T) { transactions, _ := fixtureSampleTransactions(t) block, err := block.NewBlock(types.EmptyHash(), block.HIGHEST_TARGET, transactions) if err != nil { t.Errorf("can't create a block because of %v", err) } db, err := NewDB("test.db") defer os.Remove("test.db") if err != nil { t.Errorf("error opening database: %v", err) } err = db.PutBlock(block, false) if err != nil { t.Errorf("error putting block: %v", err) } dec, err := keys.DecodeECDSAPublicKey(transactions[2].NextPublicKey) if err != nil { t.Errorf("error decoding ECDSA pubkey: %v", err) } tx, err := db.GetPreviousEnvelopeHashForPublicKey(dec) if err != nil { t.Errorf("error getting previous transaction's for a pubkey: %v", err) } assert.True(t, bytes.Compare(tx, transactions[2].Hash()) == 0) privateKey := generateECDSAKey(t) tx, err = db.GetPreviousEnvelopeHashForPublicKey(&privateKey.PublicKey) if err != nil { t.Errorf("error getting previous transaction's for a pubkey: %v", err) } assert.Nil(t, tx) }
func TestGetNextTransactionHash(t *testing.T) { transactions, _ := fixtureSampleTransactions(t) block, err := block.NewBlock(types.EmptyHash(), block.HIGHEST_TARGET, transactions) if err != nil { t.Errorf("can't create a block because of %v", err) } db, err := NewDB("test.db") defer os.Remove("test.db") if err != nil { t.Errorf("error opening database: %v", err) } err = db.PutBlock(block, false) if err != nil { t.Errorf("error putting block: %v", err) } tx, err := db.GetNextTransactionHash(transactions[0].Hash()) if err != nil { t.Errorf("error getting next transaction: %v", err) } assert.True(t, bytes.Compare(tx, transactions[1].Hash()) == 0) tx, err = db.GetNextTransactionHash(transactions[1].Hash()) if err != nil { t.Errorf("error getting next transaction: %v", err) } assert.True(t, bytes.Compare(tx, transactions[2].Hash()) == 0) tx, err = db.GetNextTransactionHash(transactions[2].Hash()) if err != nil { t.Errorf("error getting next transaction: %v", err) } assert.True(t, bytes.Compare(tx, types.EmptyHash()) == 0) }
func TransactionListener() { var msg transaction.T var blk *block.Block blockChannel := make(chan *block.Block) var transactionsPool []transaction.T var previousBlockHash types.Hash var ch chan transaction.T = make(chan transaction.T) router.PermanentSubscribe("/transaction", ch) miningEmpty := false initPool: transactionsPool = make([]transaction.T, 0) loop: select { case msg = <-ch: miningEmpty = false env.DB.PutTransaction(msg) transactionsPool = append(transactionsPool, msg) if blk, _ = env.DB.GetLastBlock(); blk == nil { previousBlockHash = types.EmptyHash() } else { previousBlockHash = blk.Hash() } if bat := prepareBAT(); bat != nil { transactionsPool = append(transactionsPool, bat) } blk, err := block.NewBlock(previousBlockHash, targetBits(), transactionsPool) if err != nil { log.Printf("Error while creating a new block: %v", err) } else { miningFactoryRequests <- MiningFactoryInstantiationRequest{Block: blk, ResponseChannel: blockChannel} } case blk = <-blockChannel: miningEmpty = false if lastBlk, _ := env.DB.GetLastBlock(); lastBlk == nil { previousBlockHash = types.EmptyHash() } else { previousBlockHash = blk.Hash() } isLastBlock := bytes.Compare(blk.PreviousBlockHash, previousBlockHash) == 0 env.DB.PutBlock(blk, isLastBlock) goto initPool default: if len(transactionsPool) == 0 && !miningEmpty { // if there are no transactions to be included into a block, try mining an empty/BAT-only block if blk, _ = env.DB.GetLastBlock(); blk == nil { previousBlockHash = types.EmptyHash() } else { previousBlockHash = blk.Hash() } if bat := prepareBAT(); bat != nil { transactionsPool = append(transactionsPool, bat) } blk, err := block.NewBlock(previousBlockHash, targetBits(), transactionsPool) if err != nil { log.Printf("Error while creating a new block: %v", err) } else { miningFactoryRequests <- MiningFactoryInstantiationRequest{Block: blk, ResponseChannel: blockChannel} miningEmpty = true } } } goto loop }