@aztec/blob-lib 1.0.0-nightly.20250608 → 1.0.0-nightly.20250610
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/blob.d.ts +1 -0
- package/dest/blob.d.ts.map +1 -1
- package/dest/blob.js +20 -1
- package/dest/blob_batching.d.ts +205 -0
- package/dest/blob_batching.d.ts.map +1 -0
- package/dest/blob_batching.js +316 -0
- package/dest/blob_batching_public_inputs.d.ts +66 -0
- package/dest/blob_batching_public_inputs.d.ts.map +1 -0
- package/dest/blob_batching_public_inputs.js +170 -0
- package/dest/index.d.ts +2 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +2 -1
- package/dest/testing.d.ts +6 -5
- package/dest/testing.d.ts.map +1 -1
- package/dest/testing.js +10 -9
- package/package.json +3 -3
- package/src/blob.ts +15 -1
- package/src/blob_batching.ts +381 -0
- package/src/blob_batching_public_inputs.ts +241 -0
- package/src/index.ts +2 -1
- package/src/testing.ts +21 -11
- package/src/trusted_setup_bit_reversed.json +4100 -0
- package/dest/blob_public_inputs.d.ts +0 -48
- package/dest/blob_public_inputs.d.ts.map +0 -1
- package/dest/blob_public_inputs.js +0 -146
- package/src/blob_public_inputs.ts +0 -157
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { BLOBS_PER_BLOCK } from '@aztec/constants';
|
|
2
|
-
import { Fr } from '@aztec/foundation/fields';
|
|
3
|
-
import { BufferReader, FieldReader, type Tuple } from '@aztec/foundation/serialize';
|
|
4
|
-
import type { FieldsOf } from '@aztec/foundation/types';
|
|
5
|
-
import { type Blob } from './blob.js';
|
|
6
|
-
/**
|
|
7
|
-
* Public inputs required to be passed from our rollup circuits to verify a blob.
|
|
8
|
-
*/
|
|
9
|
-
export declare class BlobPublicInputs {
|
|
10
|
-
/** Challenge point z (= H(H(tx_effects), kzgCommmitment). */
|
|
11
|
-
z: Fr;
|
|
12
|
-
/** Evaluation y = p(z), where p() is the blob polynomial. */
|
|
13
|
-
y: bigint;
|
|
14
|
-
/** Commitment to the blob C. */
|
|
15
|
-
kzgCommitment: Tuple<Fr, 2>;
|
|
16
|
-
constructor(
|
|
17
|
-
/** Challenge point z (= H(H(tx_effects), kzgCommmitment). */
|
|
18
|
-
z: Fr,
|
|
19
|
-
/** Evaluation y = p(z), where p() is the blob polynomial. */
|
|
20
|
-
y: bigint,
|
|
21
|
-
/** Commitment to the blob C. */
|
|
22
|
-
kzgCommitment: Tuple<Fr, 2>);
|
|
23
|
-
static empty(): BlobPublicInputs;
|
|
24
|
-
isEmpty(): boolean;
|
|
25
|
-
static fromBuffer(buffer: Buffer | BufferReader): BlobPublicInputs;
|
|
26
|
-
toBuffer(): Buffer<ArrayBufferLike>;
|
|
27
|
-
static fromFields(fields: Fr[] | FieldReader): BlobPublicInputs;
|
|
28
|
-
toFields(): Fr[];
|
|
29
|
-
static getFields(fields: FieldsOf<BlobPublicInputs>): readonly [Fr, bigint, [Fr, Fr]];
|
|
30
|
-
static fromBlob(input: Blob): BlobPublicInputs;
|
|
31
|
-
getBlobHash(): Buffer;
|
|
32
|
-
commitmentToBuffer(): Buffer;
|
|
33
|
-
equals(other: BlobPublicInputs): boolean;
|
|
34
|
-
}
|
|
35
|
-
export declare class BlockBlobPublicInputs {
|
|
36
|
-
inner: Tuple<BlobPublicInputs, typeof BLOBS_PER_BLOCK>;
|
|
37
|
-
constructor(inner: Tuple<BlobPublicInputs, typeof BLOBS_PER_BLOCK>);
|
|
38
|
-
static empty(): BlockBlobPublicInputs;
|
|
39
|
-
static fromBuffer(buffer: Buffer | BufferReader): BlockBlobPublicInputs;
|
|
40
|
-
toBuffer(): Buffer<ArrayBufferLike>;
|
|
41
|
-
static fromFields(fields: Fr[] | FieldReader): BlockBlobPublicInputs;
|
|
42
|
-
toFields(): Fr[];
|
|
43
|
-
static getFields(fields: FieldsOf<BlockBlobPublicInputs>): readonly [[BlobPublicInputs, BlobPublicInputs, BlobPublicInputs]];
|
|
44
|
-
static fromBlobs(inputs: Blob[]): BlockBlobPublicInputs;
|
|
45
|
-
getBlobsHash(): Buffer<ArrayBufferLike>;
|
|
46
|
-
toString(): string;
|
|
47
|
-
}
|
|
48
|
-
//# sourceMappingURL=blob_public_inputs.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"blob_public_inputs.d.ts","sourceRoot":"","sources":["../src/blob_public_inputs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAInD,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,KAAK,KAAK,EAAqB,MAAM,6BAA6B,CAAC;AACvG,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAExD,OAAO,EAAE,KAAK,IAAI,EAA8B,MAAM,WAAW,CAAC;AAElE;;GAEG;AACH,qBAAa,gBAAgB;IAEzB,6DAA6D;IACtD,CAAC,EAAE,EAAE;IACZ,6DAA6D;IACtD,CAAC,EAAE,MAAM;IAChB,gCAAgC;IACzB,aAAa,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;;IALlC,6DAA6D;IACtD,CAAC,EAAE,EAAE;IACZ,6DAA6D;IACtD,CAAC,EAAE,MAAM;IAChB,gCAAgC;IACzB,aAAa,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;IAGpC,MAAM,CAAC,KAAK,IAAI,gBAAgB;IAIhC,OAAO,IAAI,OAAO;IAIlB,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,GAAG,gBAAgB;IAKlE,QAAQ;IAIR,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,EAAE,GAAG,WAAW,GAAG,gBAAgB;IAa/D,QAAQ;IAUR,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,QAAQ,CAAC,gBAAgB,CAAC;IAInD,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,GAAG,gBAAgB;IAI9C,WAAW,IAAI,MAAM;IAQrB,kBAAkB,IAAI,MAAM;IAO5B,MAAM,CAAC,KAAK,EAAE,gBAAgB;CAQ/B;AAID,qBAAa,qBAAqB;IACb,KAAK,EAAE,KAAK,CAAC,gBAAgB,EAAE,OAAO,eAAe,CAAC;gBAAtD,KAAK,EAAE,KAAK,CAAC,gBAAgB,EAAE,OAAO,eAAe,CAAC;IAEzE,MAAM,CAAC,KAAK,IAAI,qBAAqB;IAIrC,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,GAAG,qBAAqB;IAKvE,QAAQ;IAIR,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,EAAE,GAAG,WAAW,GAAG,qBAAqB;IAKpE,QAAQ;IAIR,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,QAAQ,CAAC,qBAAqB,CAAC;IAIxD,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,qBAAqB;IAWvD,YAAY;IAMZ,QAAQ;CAYT"}
|
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
import { BLOBS_PER_BLOCK } from '@aztec/constants';
|
|
2
|
-
import { makeTuple } from '@aztec/foundation/array';
|
|
3
|
-
import { toBigIntBE, toBufferBE, toHex } from '@aztec/foundation/bigint-buffer';
|
|
4
|
-
import { sha256, sha256Trunc } from '@aztec/foundation/crypto';
|
|
5
|
-
import { Fr } from '@aztec/foundation/fields';
|
|
6
|
-
import { BufferReader, FieldReader, serializeToBuffer } from '@aztec/foundation/serialize';
|
|
7
|
-
import { VERSIONED_HASH_VERSION_KZG } from './blob.js';
|
|
8
|
-
/**
|
|
9
|
-
* Public inputs required to be passed from our rollup circuits to verify a blob.
|
|
10
|
-
*/ export class BlobPublicInputs {
|
|
11
|
-
z;
|
|
12
|
-
y;
|
|
13
|
-
kzgCommitment;
|
|
14
|
-
constructor(/** Challenge point z (= H(H(tx_effects), kzgCommmitment). */ z, /** Evaluation y = p(z), where p() is the blob polynomial. */ y, /** Commitment to the blob C. */ kzgCommitment){
|
|
15
|
-
this.z = z;
|
|
16
|
-
this.y = y;
|
|
17
|
-
this.kzgCommitment = kzgCommitment;
|
|
18
|
-
}
|
|
19
|
-
static empty() {
|
|
20
|
-
return new BlobPublicInputs(Fr.ZERO, 0n, [
|
|
21
|
-
Fr.ZERO,
|
|
22
|
-
Fr.ZERO
|
|
23
|
-
]);
|
|
24
|
-
}
|
|
25
|
-
isEmpty() {
|
|
26
|
-
return this.z.isZero() && this.y == 0n && this.kzgCommitment[0].isZero() && this.kzgCommitment[1].isZero();
|
|
27
|
-
}
|
|
28
|
-
static fromBuffer(buffer) {
|
|
29
|
-
const reader = BufferReader.asReader(buffer);
|
|
30
|
-
return new BlobPublicInputs(Fr.fromBuffer(reader), toBigIntBE(reader.readBytes(32)), reader.readArray(2, Fr));
|
|
31
|
-
}
|
|
32
|
-
toBuffer() {
|
|
33
|
-
return serializeToBuffer(...BlobPublicInputs.getFields(this));
|
|
34
|
-
}
|
|
35
|
-
static fromFields(fields) {
|
|
36
|
-
const reader = FieldReader.asReader(fields);
|
|
37
|
-
// TODO: Create a BigNum to fields conversion we can use here and in type_conversion.ts
|
|
38
|
-
const fromBigNum = (fieldArr)=>{
|
|
39
|
-
return BigInt(fieldArr[2].toString().concat(fieldArr[1].toString().substring(2), fieldArr[0].toString().substring(2)));
|
|
40
|
-
};
|
|
41
|
-
return new BlobPublicInputs(reader.readField(), fromBigNum(reader.readFieldArray(3)), reader.readFieldArray(2));
|
|
42
|
-
}
|
|
43
|
-
// NB: y is NOT a BN254 field, it's a larger BLS field, we cannot use serialiseToFields here as it assumes bigints will fit
|
|
44
|
-
// TODO: Create a BigNum to fields conversion we can use here and in type_conversion.ts
|
|
45
|
-
toFields() {
|
|
46
|
-
const hex = toHex(this.y, true);
|
|
47
|
-
const bigNum = [
|
|
48
|
-
Fr.fromString('0x' + hex.substring(36)),
|
|
49
|
-
Fr.fromString('0x' + hex.substring(6, 36)),
|
|
50
|
-
Fr.fromString(hex.substring(0, 6))
|
|
51
|
-
];
|
|
52
|
-
return [
|
|
53
|
-
this.z,
|
|
54
|
-
...bigNum,
|
|
55
|
-
...this.kzgCommitment
|
|
56
|
-
];
|
|
57
|
-
}
|
|
58
|
-
static getFields(fields) {
|
|
59
|
-
return [
|
|
60
|
-
fields.z,
|
|
61
|
-
fields.y,
|
|
62
|
-
fields.kzgCommitment
|
|
63
|
-
];
|
|
64
|
-
}
|
|
65
|
-
static fromBlob(input) {
|
|
66
|
-
return new BlobPublicInputs(input.challengeZ, toBigIntBE(input.evaluationY), input.commitmentToFields());
|
|
67
|
-
}
|
|
68
|
-
getBlobHash() {
|
|
69
|
-
const hash = sha256(this.commitmentToBuffer());
|
|
70
|
-
hash[0] = VERSIONED_HASH_VERSION_KZG;
|
|
71
|
-
return hash;
|
|
72
|
-
}
|
|
73
|
-
// Performs the reverse conversion of blob.commitmentToFields()
|
|
74
|
-
// 48 bytes encoded in fields as [Fr, Fr] = [0->31, 31->48]
|
|
75
|
-
commitmentToBuffer() {
|
|
76
|
-
return Buffer.concat([
|
|
77
|
-
this.kzgCommitment[0].toBuffer().subarray(1),
|
|
78
|
-
this.kzgCommitment[1].toBuffer().subarray(-17)
|
|
79
|
-
]);
|
|
80
|
-
}
|
|
81
|
-
equals(other) {
|
|
82
|
-
return this.z.equals(other.z) && this.y == other.y && this.kzgCommitment[0].equals(other.kzgCommitment[0]) && this.kzgCommitment[1].equals(other.kzgCommitment[1]);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
// NB: it is much cleaner throughout the protocol circuits to define this struct rather than use a nested array.
|
|
86
|
-
// Once we accumulate blob inputs, it should be removed, and we just use BlobPublicInputs::accumulate everywhere.
|
|
87
|
-
export class BlockBlobPublicInputs {
|
|
88
|
-
inner;
|
|
89
|
-
constructor(inner){
|
|
90
|
-
this.inner = inner;
|
|
91
|
-
}
|
|
92
|
-
static empty() {
|
|
93
|
-
return new BlockBlobPublicInputs(makeTuple(BLOBS_PER_BLOCK, BlobPublicInputs.empty));
|
|
94
|
-
}
|
|
95
|
-
static fromBuffer(buffer) {
|
|
96
|
-
const reader = BufferReader.asReader(buffer);
|
|
97
|
-
return new BlockBlobPublicInputs(reader.readArray(BLOBS_PER_BLOCK, BlobPublicInputs));
|
|
98
|
-
}
|
|
99
|
-
toBuffer() {
|
|
100
|
-
return serializeToBuffer(...BlockBlobPublicInputs.getFields(this));
|
|
101
|
-
}
|
|
102
|
-
static fromFields(fields) {
|
|
103
|
-
const reader = FieldReader.asReader(fields);
|
|
104
|
-
return new BlockBlobPublicInputs(reader.readArray(BLOBS_PER_BLOCK, BlobPublicInputs));
|
|
105
|
-
}
|
|
106
|
-
toFields() {
|
|
107
|
-
return this.inner.map((i)=>i.toFields()).flat();
|
|
108
|
-
}
|
|
109
|
-
static getFields(fields) {
|
|
110
|
-
return [
|
|
111
|
-
fields.inner
|
|
112
|
-
];
|
|
113
|
-
}
|
|
114
|
-
static fromBlobs(inputs) {
|
|
115
|
-
const inner = makeTuple(BLOBS_PER_BLOCK, BlobPublicInputs.empty);
|
|
116
|
-
if (inputs.length > BLOBS_PER_BLOCK) {
|
|
117
|
-
throw new Error(`Can only fit ${BLOBS_PER_BLOCK} in one BlockBlobPublicInputs instance (given ${inputs.length})`);
|
|
118
|
-
}
|
|
119
|
-
inputs.forEach((input, i)=>{
|
|
120
|
-
inner[i] = BlobPublicInputs.fromBlob(input);
|
|
121
|
-
});
|
|
122
|
-
return new BlockBlobPublicInputs(inner);
|
|
123
|
-
}
|
|
124
|
-
getBlobsHash() {
|
|
125
|
-
const blobHashes = this.inner.map((item)=>item.isEmpty() ? Buffer.alloc(0) : item.getBlobHash());
|
|
126
|
-
return sha256Trunc(serializeToBuffer(blobHashes));
|
|
127
|
-
}
|
|
128
|
-
// The below is used to send to L1 for proof verification
|
|
129
|
-
toString() {
|
|
130
|
-
const nonEmptyBlobs = this.inner.filter((item)=>!item.isEmpty());
|
|
131
|
-
// Write the number of blobs for L1 to verify
|
|
132
|
-
let buf = Buffer.alloc(1);
|
|
133
|
-
buf.writeUInt8(nonEmptyBlobs.length);
|
|
134
|
-
// Using standard toBuffer() does not correctly encode the commitment
|
|
135
|
-
// On L1, it's a 48 byte number, which we convert to 2 fields for use in the circuits
|
|
136
|
-
nonEmptyBlobs.forEach((blob)=>{
|
|
137
|
-
buf = Buffer.concat([
|
|
138
|
-
buf,
|
|
139
|
-
blob.z.toBuffer(),
|
|
140
|
-
toBufferBE(blob.y, 32),
|
|
141
|
-
blob.commitmentToBuffer()
|
|
142
|
-
]);
|
|
143
|
-
});
|
|
144
|
-
return buf.toString('hex');
|
|
145
|
-
}
|
|
146
|
-
}
|
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
import { BLOBS_PER_BLOCK } from '@aztec/constants';
|
|
2
|
-
import { makeTuple } from '@aztec/foundation/array';
|
|
3
|
-
import { toBigIntBE, toBufferBE, toHex } from '@aztec/foundation/bigint-buffer';
|
|
4
|
-
import { sha256, sha256Trunc } from '@aztec/foundation/crypto';
|
|
5
|
-
import { Fr } from '@aztec/foundation/fields';
|
|
6
|
-
import { BufferReader, FieldReader, type Tuple, serializeToBuffer } from '@aztec/foundation/serialize';
|
|
7
|
-
import type { FieldsOf } from '@aztec/foundation/types';
|
|
8
|
-
|
|
9
|
-
import { type Blob, VERSIONED_HASH_VERSION_KZG } from './blob.js';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Public inputs required to be passed from our rollup circuits to verify a blob.
|
|
13
|
-
*/
|
|
14
|
-
export class BlobPublicInputs {
|
|
15
|
-
constructor(
|
|
16
|
-
/** Challenge point z (= H(H(tx_effects), kzgCommmitment). */
|
|
17
|
-
public z: Fr,
|
|
18
|
-
/** Evaluation y = p(z), where p() is the blob polynomial. */
|
|
19
|
-
public y: bigint,
|
|
20
|
-
/** Commitment to the blob C. */
|
|
21
|
-
public kzgCommitment: Tuple<Fr, 2>,
|
|
22
|
-
) {}
|
|
23
|
-
|
|
24
|
-
static empty(): BlobPublicInputs {
|
|
25
|
-
return new BlobPublicInputs(Fr.ZERO, 0n, [Fr.ZERO, Fr.ZERO]);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
isEmpty(): boolean {
|
|
29
|
-
return this.z.isZero() && this.y == 0n && this.kzgCommitment[0].isZero() && this.kzgCommitment[1].isZero();
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
static fromBuffer(buffer: Buffer | BufferReader): BlobPublicInputs {
|
|
33
|
-
const reader = BufferReader.asReader(buffer);
|
|
34
|
-
return new BlobPublicInputs(Fr.fromBuffer(reader), toBigIntBE(reader.readBytes(32)), reader.readArray(2, Fr));
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
toBuffer() {
|
|
38
|
-
return serializeToBuffer(...BlobPublicInputs.getFields(this));
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
static fromFields(fields: Fr[] | FieldReader): BlobPublicInputs {
|
|
42
|
-
const reader = FieldReader.asReader(fields);
|
|
43
|
-
// TODO: Create a BigNum to fields conversion we can use here and in type_conversion.ts
|
|
44
|
-
const fromBigNum = (fieldArr: Fr[]) => {
|
|
45
|
-
return BigInt(
|
|
46
|
-
fieldArr[2].toString().concat(fieldArr[1].toString().substring(2), fieldArr[0].toString().substring(2)),
|
|
47
|
-
);
|
|
48
|
-
};
|
|
49
|
-
return new BlobPublicInputs(reader.readField(), fromBigNum(reader.readFieldArray(3)), reader.readFieldArray(2));
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// NB: y is NOT a BN254 field, it's a larger BLS field, we cannot use serialiseToFields here as it assumes bigints will fit
|
|
53
|
-
// TODO: Create a BigNum to fields conversion we can use here and in type_conversion.ts
|
|
54
|
-
toFields() {
|
|
55
|
-
const hex = toHex(this.y, true);
|
|
56
|
-
const bigNum = [
|
|
57
|
-
Fr.fromString('0x' + hex.substring(36)),
|
|
58
|
-
Fr.fromString('0x' + hex.substring(6, 36)),
|
|
59
|
-
Fr.fromString(hex.substring(0, 6)),
|
|
60
|
-
];
|
|
61
|
-
return [this.z, ...bigNum, ...this.kzgCommitment];
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
static getFields(fields: FieldsOf<BlobPublicInputs>) {
|
|
65
|
-
return [fields.z, fields.y, fields.kzgCommitment] as const;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
static fromBlob(input: Blob): BlobPublicInputs {
|
|
69
|
-
return new BlobPublicInputs(input.challengeZ, toBigIntBE(input.evaluationY), input.commitmentToFields());
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
getBlobHash(): Buffer {
|
|
73
|
-
const hash = sha256(this.commitmentToBuffer());
|
|
74
|
-
hash[0] = VERSIONED_HASH_VERSION_KZG;
|
|
75
|
-
return hash;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// Performs the reverse conversion of blob.commitmentToFields()
|
|
79
|
-
// 48 bytes encoded in fields as [Fr, Fr] = [0->31, 31->48]
|
|
80
|
-
commitmentToBuffer(): Buffer {
|
|
81
|
-
return Buffer.concat([
|
|
82
|
-
this.kzgCommitment[0].toBuffer().subarray(1),
|
|
83
|
-
this.kzgCommitment[1].toBuffer().subarray(-17),
|
|
84
|
-
]);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
equals(other: BlobPublicInputs) {
|
|
88
|
-
return (
|
|
89
|
-
this.z.equals(other.z) &&
|
|
90
|
-
this.y == other.y &&
|
|
91
|
-
this.kzgCommitment[0].equals(other.kzgCommitment[0]) &&
|
|
92
|
-
this.kzgCommitment[1].equals(other.kzgCommitment[1])
|
|
93
|
-
);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// NB: it is much cleaner throughout the protocol circuits to define this struct rather than use a nested array.
|
|
98
|
-
// Once we accumulate blob inputs, it should be removed, and we just use BlobPublicInputs::accumulate everywhere.
|
|
99
|
-
export class BlockBlobPublicInputs {
|
|
100
|
-
constructor(public inner: Tuple<BlobPublicInputs, typeof BLOBS_PER_BLOCK>) {}
|
|
101
|
-
|
|
102
|
-
static empty(): BlockBlobPublicInputs {
|
|
103
|
-
return new BlockBlobPublicInputs(makeTuple(BLOBS_PER_BLOCK, BlobPublicInputs.empty));
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
static fromBuffer(buffer: Buffer | BufferReader): BlockBlobPublicInputs {
|
|
107
|
-
const reader = BufferReader.asReader(buffer);
|
|
108
|
-
return new BlockBlobPublicInputs(reader.readArray(BLOBS_PER_BLOCK, BlobPublicInputs));
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
toBuffer() {
|
|
112
|
-
return serializeToBuffer(...BlockBlobPublicInputs.getFields(this));
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
static fromFields(fields: Fr[] | FieldReader): BlockBlobPublicInputs {
|
|
116
|
-
const reader = FieldReader.asReader(fields);
|
|
117
|
-
return new BlockBlobPublicInputs(reader.readArray(BLOBS_PER_BLOCK, BlobPublicInputs));
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
toFields() {
|
|
121
|
-
return this.inner.map(i => i.toFields()).flat();
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
static getFields(fields: FieldsOf<BlockBlobPublicInputs>) {
|
|
125
|
-
return [fields.inner] as const;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
static fromBlobs(inputs: Blob[]): BlockBlobPublicInputs {
|
|
129
|
-
const inner = makeTuple(BLOBS_PER_BLOCK, BlobPublicInputs.empty);
|
|
130
|
-
if (inputs.length > BLOBS_PER_BLOCK) {
|
|
131
|
-
throw new Error(`Can only fit ${BLOBS_PER_BLOCK} in one BlockBlobPublicInputs instance (given ${inputs.length})`);
|
|
132
|
-
}
|
|
133
|
-
inputs.forEach((input, i) => {
|
|
134
|
-
inner[i] = BlobPublicInputs.fromBlob(input);
|
|
135
|
-
});
|
|
136
|
-
return new BlockBlobPublicInputs(inner);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
getBlobsHash() {
|
|
140
|
-
const blobHashes = this.inner.map(item => (item.isEmpty() ? Buffer.alloc(0) : item.getBlobHash()));
|
|
141
|
-
return sha256Trunc(serializeToBuffer(blobHashes));
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// The below is used to send to L1 for proof verification
|
|
145
|
-
toString() {
|
|
146
|
-
const nonEmptyBlobs = this.inner.filter(item => !item.isEmpty());
|
|
147
|
-
// Write the number of blobs for L1 to verify
|
|
148
|
-
let buf = Buffer.alloc(1);
|
|
149
|
-
buf.writeUInt8(nonEmptyBlobs.length);
|
|
150
|
-
// Using standard toBuffer() does not correctly encode the commitment
|
|
151
|
-
// On L1, it's a 48 byte number, which we convert to 2 fields for use in the circuits
|
|
152
|
-
nonEmptyBlobs.forEach(blob => {
|
|
153
|
-
buf = Buffer.concat([buf, blob.z.toBuffer(), toBufferBE(blob.y, 32), blob.commitmentToBuffer()]);
|
|
154
|
-
});
|
|
155
|
-
return buf.toString('hex');
|
|
156
|
-
}
|
|
157
|
-
}
|