bmt.go 1.35 KB
Newer Older
acud's avatar
acud committed
1 2 3 4
// Copyright 2020 The Swarm Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

5
package bmt
acud's avatar
acud committed
6 7

import (
8
	"errors"
acud's avatar
acud committed
9

acud's avatar
acud committed
10
	"github.com/ethersphere/bee/pkg/bmtpool"
11
	"github.com/ethersphere/bee/pkg/file/pipeline"
acud's avatar
acud committed
12 13 14
	"github.com/ethersphere/bee/pkg/swarm"
)

15 16 17 18
var (
	errInvalidData = errors.New("bmt: invalid data")
)

acud's avatar
acud committed
19
type bmtWriter struct {
20
	next pipeline.ChainWriter
acud's avatar
acud committed
21 22
}

23
// NewBmtWriter returns a new bmtWriter. Partial writes are not supported.
acud's avatar
acud committed
24
// Note: branching factor is the BMT branching factor, not the merkle trie branching factor.
acud's avatar
acud committed
25
func NewBmtWriter(next pipeline.ChainWriter) pipeline.ChainWriter {
acud's avatar
acud committed
26 27 28 29 30
	return &bmtWriter{
		next: next,
	}
}

31
// ChainWrite writes data in chain. It assumes span has been prepended to the data.
acud's avatar
acud committed
32
// The span can be encrypted or unencrypted.
33 34 35 36
func (w *bmtWriter) ChainWrite(p *pipeline.PipeWriteArgs) error {
	if len(p.Data) < swarm.SpanSize {
		return errInvalidData
	}
acud's avatar
acud committed
37
	hasher := bmtpool.Get()
38 39
	hasher.SetHeader(p.Data[:swarm.SpanSize])
	_, err := hasher.Write(p.Data[swarm.SpanSize:])
acud's avatar
acud committed
40
	if err != nil {
acud's avatar
acud committed
41
		bmtpool.Put(hasher)
acud's avatar
acud committed
42 43
		return err
	}
44 45
	p.Ref, err = hasher.Hash(nil)
	bmtpool.Put(hasher)
acud's avatar
acud committed
46 47 48
	if err != nil {
		return err
	}
acud's avatar
acud committed
49

50
	return w.next.ChainWrite(p)
acud's avatar
acud committed
51 52 53
}

// sum calls the next writer for the cryptographic sum
54 55
func (w *bmtWriter) Sum() ([]byte, error) {
	return w.next.Sum()
acud's avatar
acud committed
56
}