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 }