// safePut is used to put a value into an immutable ticket treap, returning // the mutated, immutable treap given as a result. It first checks to see if // there is already this key in the treap. If there is, it returns an error. // TODO This function could also check to make sure the states of the ticket // treap value are valid. func safePut(t *tickettreap.Immutable, k tickettreap.Key, v *tickettreap.Value) (*tickettreap.Immutable, error) { if t.Has(k) { return nil, stakeRuleError(ErrDuplicateTicket, fmt.Sprintf("attempted "+ "to insert duplicate key %v into treap", chainhash.Hash(k))) } return t.Put(k, v), nil }
func TestFetchWinnersErrors(t *testing.T) { treap := new(tickettreap.Immutable) for i := 0; i < 0xff; i++ { h := chainhash.HashFuncH([]byte{byte(i)}) v := &tickettreap.Value{ Height: uint32(i), Missed: i%2 == 0, Revoked: i%2 != 0, Spent: i%2 == 0, Expired: i%2 != 0, } treap = treap.Put(tickettreap.Key(h), v) } // No indexes. _, err := fetchWinners(nil, treap) if err == nil { t.Errorf("Expected nil slice error") } // No treap. _, err = fetchWinners([]int{1, 2, 3, 4, -1}, nil) if err == nil { t.Errorf("Expected nil treap error") } // Bad index too small. _, err = fetchWinners([]int{1, 2, 3, 4, -1}, treap) if err == nil { t.Errorf("Expected index too small error") } // Bad index too big. _, err = fetchWinners([]int{1, 2, 3, 4, 256}, treap) if err == nil { t.Errorf("Expected index too big error") } }
// copyNode copies a stake node so that it can be manipulated for tests. func copyNode(n *Node) *Node { liveTickets := new(tickettreap.Immutable) n.liveTickets.ForEach(func(k tickettreap.Key, v *tickettreap.Value) bool { liveTickets.Put(k, v) return true }) missedTickets := new(tickettreap.Immutable) n.missedTickets.ForEach(func(k tickettreap.Key, v *tickettreap.Value) bool { missedTickets.Put(k, v) return true }) revokedTickets := new(tickettreap.Immutable) n.revokedTickets.ForEach(func(k tickettreap.Key, v *tickettreap.Value) bool { revokedTickets.Put(k, v) return true }) databaseUndoUpdate := make(UndoTicketDataSlice, len(n.databaseUndoUpdate)) copy(databaseUndoUpdate[:], n.databaseUndoUpdate[:]) databaseBlockTickets := make([]chainhash.Hash, len(n.databaseBlockTickets)) copy(databaseBlockTickets[:], n.databaseBlockTickets[:]) nextWinners := make([]chainhash.Hash, len(n.nextWinners)) copy(nextWinners[:], n.nextWinners[:]) var finalState [6]byte copy(finalState[:], n.finalState[:]) return &Node{ height: n.height, liveTickets: liveTickets, missedTickets: missedTickets, revokedTickets: revokedTickets, databaseUndoUpdate: databaseUndoUpdate, databaseBlockTickets: databaseBlockTickets, nextWinners: nextWinners, finalState: finalState, params: n.params, } }