// decodeFlags decodes transaction flags from a single byte into their respective // data types. func decodeFlags(b byte) (bool, bool, stake.TxType, bool) { isCoinBase := b&0x01 != 0 hasExpiry := b&(1<<1) != 0 fullySpent := b&(1<<4) != 0 txType := stake.TxType((b & txTypeBitmask) >> txTypeShift) return isCoinBase, hasExpiry, txType, fullySpent }
// TestStakeTxFeePrioHeap tests the priority heaps including the stake types for // both transaction fees per KB and transaction priority. It ensures that the // primary sorting is first by stake type, and then by the latter chosen priority // type. func TestStakeTxFeePrioHeap(t *testing.T) { numElements := 1000 ph := newTxPriorityQueue(numElements, txPQByStakeAndFee) for i := 0; i < numElements; i++ { randType := stake.TxType(rand.Intn(4)) randPrio := rand.Float64() * 100 randFeePerKB := rand.Float64() * 10 prioItem := &txPrioItem{ tx: nil, txType: randType, priority: randPrio, feePerKB: randFeePerKB, } heap.Push(ph, prioItem) } // Test sorting by stake and fee per KB. last := &txPrioItem{ tx: nil, txType: stake.TxTypeSSGen, priority: 10000.0, feePerKB: 10000.0, } for i := 0; i < numElements; i++ { prioItem := heap.Pop(ph) txpi, ok := prioItem.(*txPrioItem) if ok { if txpi.feePerKB > last.feePerKB && compareStakePriority(txpi, last) >= 0 { t.Errorf("bad pop: %v fee per KB was more than last of %v "+ "while the txtype was %v but last was %v", txpi.feePerKB, last.feePerKB, txpi.txType, last.txType) } last = txpi } } ph = newTxPriorityQueue(numElements, txPQByStakeAndPriority) for i := 0; i < numElements; i++ { randType := stake.TxType(rand.Intn(4)) randPrio := rand.Float64() * 100 randFeePerKB := rand.Float64() * 10 prioItem := &txPrioItem{ tx: nil, txType: randType, priority: randPrio, feePerKB: randFeePerKB, } heap.Push(ph, prioItem) } // Test sorting by stake and priority. last = &txPrioItem{ tx: nil, txType: stake.TxTypeSSGen, priority: 10000.0, feePerKB: 10000.0, } for i := 0; i < numElements; i++ { prioItem := heap.Pop(ph) txpi, ok := prioItem.(*txPrioItem) if ok { if txpi.priority > last.priority && compareStakePriority(txpi, last) >= 0 { t.Errorf("bad pop: %v fee per KB was more than last of %v "+ "while the txtype was %v but last was %v", txpi.feePerKB, last.feePerKB, txpi.txType, last.txType) } last = txpi } } ph = newTxPriorityQueue(numElements, txPQByStakeAndFeeAndThenPriority) for i := 0; i < numElements; i++ { randType := stake.TxType(rand.Intn(4)) randPrio := rand.Float64() * 100 randFeePerKB := rand.Float64() * 10 prioItem := &txPrioItem{ tx: nil, txType: randType, priority: randPrio, feePerKB: randFeePerKB, } heap.Push(ph, prioItem) } // Test sorting with fees per KB for high stake priority, then // priority for low stake priority. last = &txPrioItem{ tx: nil, txType: stake.TxTypeSSGen, priority: 10000.0, feePerKB: 10000.0, } for i := 0; i < numElements; i++ { prioItem := heap.Pop(ph) txpi, ok := prioItem.(*txPrioItem) if ok { bothAreLowStakePriority := txStakePriority(txpi.txType) == regOrRevocPriority && txStakePriority(last.txType) == regOrRevocPriority if !bothAreLowStakePriority { if txpi.feePerKB > last.feePerKB && compareStakePriority(txpi, last) >= 0 { t.Errorf("bad pop: %v fee per KB was more than last of %v "+ "while the txtype was %v but last was %v", txpi.feePerKB, last.feePerKB, txpi.txType, last.txType) } } if bothAreLowStakePriority { if txpi.priority > last.priority && compareStakePriority(txpi, last) >= 0 { t.Errorf("bad pop: %v priority was more than last of %v "+ "while the txtype was %v but last was %v", txpi.feePerKB, last.feePerKB, txpi.txType, last.txType) } } last = txpi } } }