/
batch.go
71 lines (59 loc) · 1.75 KB
/
batch.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package committee
import (
"fmt"
"github.com/oasisprotocol/oasis-core/go/common/crypto/hash"
"github.com/oasisprotocol/oasis-core/go/roothash/api/commitment"
"github.com/oasisprotocol/oasis-core/go/runtime/transaction"
"github.com/oasisprotocol/oasis-core/go/runtime/txpool"
)
// unresolvedBatch is a batch that may still need to be resolved (fetched from storage).
type unresolvedBatch struct {
proposal *commitment.Proposal
batch transaction.RawBatch
missingTxs map[hash.Hash]int
maxBatchSizeBytes uint64
}
func (ub *unresolvedBatch) String() string {
switch {
case ub.proposal != nil:
return fmt.Sprintf("UnresolvedBatch{hash: %s}", ub.proposal.Header.BatchHash)
default:
return "UnresolvedBatch{?}"
}
}
func (ub *unresolvedBatch) hash() hash.Hash {
if ub.proposal == nil {
return hash.Hash{}
}
return ub.proposal.Header.BatchHash
}
func (ub *unresolvedBatch) resolve(txPool txpool.TransactionPool) (transaction.RawBatch, error) {
if ub.batch != nil {
return ub.batch, nil
}
if ub.proposal == nil {
return nil, fmt.Errorf("resolve called on unresolvable batch")
}
if len(ub.proposal.Batch) == 0 {
return transaction.RawBatch{}, nil
}
resolvedBatch, missingTxs := txPool.GetKnownBatch(ub.proposal.Batch)
if len(missingTxs) > 0 {
ub.missingTxs = missingTxs
return nil, nil
}
ub.missingTxs = nil
var (
batch transaction.RawBatch
totalSizeBytes int
)
for _, checkedTx := range resolvedBatch {
totalSizeBytes = totalSizeBytes + checkedTx.Size()
if ub.maxBatchSizeBytes > 0 && uint64(totalSizeBytes) > ub.maxBatchSizeBytes {
return nil, fmt.Errorf("batch too large (max: %d size: >=%d)", ub.maxBatchSizeBytes, totalSizeBytes)
}
batch = append(batch, checkedTx.Raw())
}
ub.batch = batch
return batch, nil
}