-
Notifications
You must be signed in to change notification settings - Fork 39
/
batch.go
120 lines (106 loc) · 3.08 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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package core
import (
"math/big"
"sync/atomic"
"github.com/ten-protocol/go-ten/go/common/compression"
"github.com/ten-protocol/go-ten/go/enclave/crypto"
gethcommon "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ten-protocol/go-ten/go/common"
)
// Batch Data structure only for the internal use of the enclave since transactions are in clear
type Batch struct {
Header *common.BatchHeader
hash atomic.Value
Transactions []*common.L2Tx
}
// Hash returns the keccak256 hash of b's header.
// The hash is computed on the first call and cached thereafter.
func (b *Batch) Hash() common.L2BatchHash {
if hash := b.hash.Load(); hash != nil {
return hash.(common.L2BatchHash)
}
v := b.Header.Hash()
b.hash.Store(v)
return v
}
func (b *Batch) ResetHash() {
b.hash = atomic.Value{}
}
func (b *Batch) Size() (int, error) {
bytes, err := rlp.EncodeToBytes(b)
return len(bytes), err
}
func (b *Batch) Encode() ([]byte, error) {
return rlp.EncodeToBytes(b)
}
func (b *Batch) NumberU64() uint64 { return b.Header.Number.Uint64() }
func (b *Batch) Number() *big.Int { return new(big.Int).Set(b.Header.Number) }
func (b *Batch) SeqNo() *big.Int { return new(big.Int).Set(b.Header.SequencerOrderNo) }
func (b *Batch) ToExtBatch(transactionBlobCrypto crypto.DataEncryptionService, compression compression.DataCompressionService) (*common.ExtBatch, error) {
txHashes := make([]gethcommon.Hash, len(b.Transactions))
for idx, tx := range b.Transactions {
txHashes[idx] = tx.Hash()
}
bytes, err := rlp.EncodeToBytes(b.Transactions)
if err != nil {
return nil, err
}
compressed, err := compression.CompressBatch(bytes)
if err != nil {
return nil, err
}
enc, err := transactionBlobCrypto.Encrypt(compressed)
if err != nil {
return nil, err
}
return &common.ExtBatch{
Header: b.Header,
TxHashes: txHashes,
EncryptedTxBlob: enc,
}, nil
}
func ToBatch(extBatch *common.ExtBatch, transactionBlobCrypto crypto.DataEncryptionService, compression compression.DataCompressionService) (*Batch, error) {
compressed, err := transactionBlobCrypto.Decrypt(extBatch.EncryptedTxBlob)
if err != nil {
return nil, err
}
encoded, err := compression.Decompress(compressed)
if err != nil {
return nil, err
}
var txs []*common.L2Tx
err = rlp.DecodeBytes(encoded, &txs)
if err != nil {
return nil, err
}
return &Batch{
Header: extBatch.Header,
Transactions: txs,
}, nil
}
func DeterministicEmptyBatch(
parent *common.BatchHeader,
block *types.Block,
time uint64,
sequencerNo *big.Int,
baseFee *big.Int,
coinbase gethcommon.Address,
) *Batch {
h := common.BatchHeader{
ParentHash: parent.Hash(),
L1Proof: block.Hash(),
Number: big.NewInt(0).Add(parent.Number, big.NewInt(1)),
SequencerOrderNo: sequencerNo,
// todo (#1548) - Consider how this time should align with the time of the L1 block used as proof.
Time: time,
BaseFee: baseFee,
Coinbase: coinbase,
GasLimit: parent.GasLimit,
}
b := Batch{
Header: &h,
}
return &b
}