// NewMsgCmpctBlockFromBlock builds a cmpctblock message from a block
// using a known inventory map. If a given transaction is not in the
// known inventory map, we will append it as a PrefilledTx. Otherwise
// we'll add the short ID of the transaction.
NewMsgCmpctBlockFromBlock builds a cmpctblock message from a block
using a known inventory map. If a given transaction is not in the
known inventory map, we will append it as a PrefilledTx. Otherwise
we'll add the short ID of the transaction.
// NewMsgCmpctBlockFromBlock builds a cmpctblock message from a block // using a known inventory map . If a given transaction is not in the // known inventory map we will append it as a PrefilledTx . Otherwise // we ' ll add the short ID of the transaction .
func NewMsgCmpctBlockFromBlock(block *MsgBlock, knownInventory map[chainhash.Hash]bool) (*MsgCmpctBlock, error) {
	nonce, err := RandomUint64()
	if err != nil {
		return nil, err
	}
	msg := &MsgCmpctBlock{
		Header: block.Header,
		Nonce:  nonce,
	}
	var buf bytes.Buffer
	if err := block.Header.Serialize(&buf); err != nil {
		return nil, err
	}
	nonceBytes := make([]byte, 8)
	binary.LittleEndian.PutUint64(nonceBytes, msg.Nonce)
	headerWithNonce := append(buf.Bytes(), nonceBytes...)
	headerHash := sha256.Sum256(headerWithNonce)
	key0 := binary.LittleEndian.Uint64(headerHash[0:8])
	key1 := binary.LittleEndian.Uint64(headerHash[8:16])
	lastIndex := 0
	for i, tx := range block.Transactions {
		if knownInventory[tx.TxHash()] { 
			txHash := tx.TxHash()
			sum64 := siphash.Hash(key0, key1, txHash.CloneBytes())
			shortIDBytes := make([]byte, 8)
			binary.LittleEndian.PutUint64(shortIDBytes, sum64)
			var shortID [ShortIDSize]byte
			copy(shortID[:], shortIDBytes[:ShortIDSize])
			msg.ShortIDs = append(msg.ShortIDs, shortID)
		} else { 
			ptx := &PrefilledTx{
				Index: uint32(i - lastIndex),
				Tx:    tx,
			}
			lastIndex = i + 1
			msg.PrefilledTxs = append(msg.PrefilledTxs, ptx)
		}
	}
	return msg, nil
}
func NewMsgCmpctBlockFromBlock ( block * MsgBlock , knownInventory map [ chainhash . Hash ] bool ) ( * MsgCmpctBlock , error ) { nonce , err := RandomUint64 ( ) if err != nil { return nil , err } msg := & MsgCmpctBlock { Header : block . Header , Nonce : nonce , } var buf bytes . Buffer if err := block . Header . Serialize ( & buf ) ; err != nil { return nil , err } nonceBytes := make ( [ ] byte , 8 ) binary . LittleEndian . PutUint64 ( nonceBytes , msg . Nonce ) headerWithNonce := append ( buf . Bytes ( ) , nonceBytes ... ) headerHash := sha256 . Sum256 ( headerWithNonce ) key0 := binary . LittleEndian . Uint64 ( headerHash [ 0 : 8 ] ) key1 := binary . LittleEndian . Uint64 ( headerHash [ 8 : 16 ] ) lastIndex := 0 for i , tx := range block . Transactions { if knownInventory [ tx . TxHash ( ) ] { txHash := tx . TxHash ( ) sum64 := siphash . Hash ( key0 , key1 , txHash . CloneBytes ( ) ) shortIDBytes := make ( [ ] byte , 8 ) binary . LittleEndian . PutUint64 ( shortIDBytes , sum64 ) var shortID [ ShortIDSize ] byte copy ( shortID [ : ] , shortIDBytes [ : ShortIDSize ] ) msg . ShortIDs = append ( msg . ShortIDs , shortID ) } else { ptx := & PrefilledTx { Index : uint32 ( i - lastIndex ) , Tx : tx , } lastIndex = i + 1 msg . PrefilledTxs = append ( msg . PrefilledTxs , ptx ) } } return msg , nil }
NewMsgCmpctBlockFromBlock builds a cmpctblock message from a block
using a known inventory map.
NewMsgCmpctBlockFromBlock builds a cmpctblock message from a block using a known inventory map .
// To calculate the siphash keys we need to append the little endian // nonce to the block header. // Hash the result once with sha256 // The keys are the first two little endian uint64s in the resulting // byte array. // The other peer knows the transaction so we can just send the short IDs. // The other peer doesn't know the transaction so we just send the full tx.