// newManagedAddressWithoutPrivKey returns a new managed address based on the // passed account, public key, and whether or not the public key should be // compressed. func newManagedAddressWithoutPrivKey(m *Manager, account uint32, pubKey chainec.PublicKey, compressed bool) (*managedAddress, error) { // Create a pay-to-pubkey-hash address from the public key. var pubKeyHash []byte if compressed { pubKeyHash = dcrutil.Hash160(pubKey.SerializeCompressed()) } else { pubKeyHash = dcrutil.Hash160(pubKey.SerializeUncompressed()) } address, err := dcrutil.NewAddressPubKeyHash(pubKeyHash, m.chainParams, chainec.ECTypeSecp256k1) if err != nil { return nil, err } return &managedAddress{ manager: m, address: address, account: account, imported: false, internal: false, multisig: false, compressed: compressed, pubKey: pubKey, privKeyEncrypted: nil, privKeyCT: nil, }, nil }
// Exists returns true if an existing entry of 'sig' over 'sigHash' for public // key 'pubKey' is found within the SigCache. Otherwise, false is returned. // // NOTE: This function is safe for concurrent access. Readers won't be blocked // unless there exists a writer, adding an entry to the SigCache. func (s *SigCache) Exists(sigHash chainhash.Hash, sig chainec.Signature, pubKey chainec.PublicKey) bool { info := sigInfo{sigHash, string(sig.Serialize()), string(pubKey.SerializeCompressed())} s.RLock() _, ok := s.validSigs[info] s.RUnlock() return ok }
// Exists returns true if an existing entry of 'sig' over 'sigHash' for public // key 'pubKey' is found within the SigCache. Otherwise, false is returned. // // NOTE: This function is safe for concurrent access. Readers won't be blocked // unless there exists a writer, adding an entry to the SigCache. func (s *SigCache) Exists(sigHash chainhash.Hash, sig chainec.Signature, pubKey chainec.PublicKey) bool { s.RLock() defer s.RUnlock() if entry, ok := s.validSigs[sigHash]; ok { pkEqual := bytes.Equal(entry.pubKey.SerializeCompressed(), pubKey.SerializeCompressed()) sigEqual := bytes.Equal(entry.sig.Serialize(), sig.Serialize()) return pkEqual && sigEqual } return false }
// SerializePubKey serializes the associated public key of the imported or // exported private key in compressed format. The serialization format // chosen depends on the value of w.ecType. func (w *WIF) SerializePubKey() []byte { pkx, pky := w.PrivKey.Public() var pk chainec.PublicKey switch w.ecType { case chainec.ECTypeSecp256k1: pk = chainec.Secp256k1.NewPublicKey(pkx, pky) case chainec.ECTypeEdwards: pk = chainec.Edwards.NewPublicKey(pkx, pky) case chainec.ECTypeSecSchnorr: pk = chainec.SecSchnorr.NewPublicKey(pkx, pky) } return pk.SerializeCompressed() }
// Add adds an entry for a signature over 'sigHash' under public key 'pubKey' // to the signature cache. In the event that the SigCache is 'full', an // existing entry it randomly chosen to be evicted in order to make space for // the new entry. // // NOTE: This function is safe for concurrent access. Writers will block // simultaneous readers until function execution has concluded. func (s *SigCache) Add(sigHash chainhash.Hash, sig chainec.Signature, pubKey chainec.PublicKey) { s.Lock() defer s.Unlock() if s.maxEntries <= 0 { return } // If adding this new entry will put us over the max number of allowed // entries, then evict an entry. if uint(len(s.validSigs)+1) > s.maxEntries { // Generate a cryptographically random hash. randHashBytes := make([]byte, chainhash.HashSize) _, err := rand.Read(randHashBytes) if err != nil { // Failure to read a random hash results in the proposed // entry not being added to the cache since we are // unable to evict any existing entries. return } // Try to find the first entry that is greater than the random // hash. Use the first entry (which is already pseudo random due // to Go's range statement over maps) as a fall back if none of // the hashes in the rejected transactions pool are larger than // the random hash. var foundEntry sigInfo for sigEntry := range s.validSigs { if foundEntry.sig == "" { foundEntry = sigEntry } if bytes.Compare(sigEntry.sigHash.Bytes(), randHashBytes) > 0 { foundEntry = sigEntry break } } delete(s.validSigs, foundEntry) } info := sigInfo{sigHash, string(sig.Serialize()), string(pubKey.SerializeCompressed())} s.validSigs[info] = struct{}{} }