github.com/storacha/go-ucanto@v0.7.2/core/ipld/block/block.go (about)

     1  package block
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  
     7  	"github.com/ipfs/go-cid"
     8  	"github.com/ipld/go-ipld-prime"
     9  	cidlink "github.com/ipld/go-ipld-prime/linking/cid"
    10  	"github.com/ipld/go-ipld-prime/node/bindnode"
    11  	"github.com/ipld/go-ipld-prime/schema"
    12  	"github.com/storacha/go-ucanto/core/ipld/codec"
    13  	"github.com/storacha/go-ucanto/core/ipld/hash"
    14  )
    15  
    16  type Block interface {
    17  	Link() ipld.Link
    18  	Bytes() []byte
    19  }
    20  
    21  type block struct {
    22  	link  ipld.Link
    23  	bytes []byte
    24  }
    25  
    26  func (b *block) Link() ipld.Link {
    27  	return b.link
    28  }
    29  
    30  func (b *block) Bytes() []byte {
    31  	return b.bytes
    32  }
    33  
    34  func NewBlock(link ipld.Link, bytes []byte) Block {
    35  	return &block{link, bytes}
    36  }
    37  
    38  func Encode(value any, typ schema.Type, codec codec.Encoder, hasher hash.Hasher, opts ...bindnode.Option) (Block, error) {
    39  	b, err := codec.Encode(value, typ, opts...)
    40  	if err != nil {
    41  		return nil, err
    42  	}
    43  
    44  	d, err := hasher.Sum(b)
    45  	if err != nil {
    46  		return nil, err
    47  	}
    48  
    49  	l := cidlink.Link{Cid: cid.NewCidV1(codec.Code(), d.Bytes())}
    50  	return NewBlock(l, b), nil
    51  }
    52  
    53  func Decode(block Block, bind any, typ schema.Type, codec codec.Decoder, hasher hash.Hasher, opts ...bindnode.Option) error {
    54  	err := codec.Decode(block.Bytes(), bind, typ, opts...)
    55  	if err != nil {
    56  		return err
    57  	}
    58  
    59  	d, err := hasher.Sum(block.Bytes())
    60  	if err != nil {
    61  		return err
    62  	}
    63  
    64  	c := cid.NewCidV1(codec.Code(), d.Bytes())
    65  	if !bytes.Equal(c.Bytes(), []byte(block.Link().Binary())) {
    66  		return fmt.Errorf("data integrity error")
    67  	}
    68  
    69  	return nil
    70  }