Skip to content

Commit df74f53

Browse files
authored
Batch Set Unicode Data to Reduce # of TXs Required to Init (#18)
* Batch set unicode data to reduce # of transactions * Fix typo * Log entire batch on failure
1 parent 8a9e355 commit df74f53

4 files changed

Lines changed: 85 additions & 4 deletions

File tree

contracts/UnicodeData.sol

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ contract UnicodeData is Ownable {
259259
return char;
260260
}
261261

262-
/// @notice This should only be used by the owner to initialize and update Unicode character database
262+
/// @notice This is only used by the owner to initialize and update Unicode character database
263263
/// @param _codePoint The Unicode code point to set
264264
/// @param _data The character data
265265
function set(uint32 _codePoint, Character calldata _data) external onlyOwner {
@@ -268,6 +268,28 @@ contract UnicodeData is Ownable {
268268
characters[_codePoint] = _data;
269269
}
270270

271+
/// @notice This is only used by the owner to initialize and update Unicode character database
272+
/// @param _codePoints The Unicode code points to set
273+
/// @param _data The list of character data to set
274+
/// @dev Order matters! Order of _data must match the order of _codePoints
275+
function setBatch(uint32[] calldata _codePoints, Character[] calldata _data)
276+
external
277+
onlyOwner
278+
{
279+
uint256 len = _codePoints.length;
280+
uint256 i;
281+
282+
for (i = 0; i < len; i++) {
283+
uint32 codePoint = _codePoints[i];
284+
// Require name to be non-empty!
285+
require(
286+
bytes(_data[i].name).length > 0,
287+
"character name must not be empty"
288+
);
289+
characters[codePoint] = _data[i];
290+
}
291+
}
292+
271293
// -------
272294
// Getters
273295
// -------

docs/UnicodeData.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -796,7 +796,7 @@ function renounceOwnership() external nonpayable
796796
function set(uint32 _codePoint, UnicodeData.Character _data) external nonpayable
797797
```
798798

799-
This should only be used by the owner to initialize and update Unicode character database
799+
This is onlyty used by the owner to initialize and update Unicode character database
800800

801801

802802

@@ -807,6 +807,23 @@ This should only be used by the owner to initialize and update Unicode character
807807
| _codePoint | uint32 | The Unicode code point to set
808808
| _data | UnicodeData.Character | The character data
809809

810+
### setBatch
811+
812+
```solidity
813+
function setBatch(uint32[] _codePoints, UnicodeData.Character[] _data) external nonpayable
814+
```
815+
816+
This is only used by the owner to initialize and update Unicode character database
817+
818+
*Order matters! Order of _data must match the order of _codePoints*
819+
820+
#### Parameters
821+
822+
| Name | Type | Description |
823+
|---|---|---|
824+
| _codePoints | uint32[] | The Unicode code points to set
825+
| _data | UnicodeData.Character[] | The list of character data to set
826+
810827
### titlecase
811828

812829
```solidity

package-lock.json

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

scripts/initialization.ts

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ import { Contract } from "ethers";
33
import { Character } from "./types";
44
import { getUnicodeData } from "./unicode-data";
55

6+
// roughly the number of characters we can set within the gas limit
7+
const BATCH_SIZE = 125;
8+
69
const charToParameter = (c: Character) =>
710
Object.values({
811
name: c.name,
@@ -25,7 +28,14 @@ export const initializeUnicodeData = async (contract: Contract) => {
2528
const characters = await getUnicodeData();
2629

2730
const total = characters.length;
31+
const numBatches = total / BATCH_SIZE;
2832
let count = 0;
33+
let failed = false;
34+
let batch = {
35+
codes: [],
36+
data: [],
37+
};
38+
2939
for (let char of characters) {
3040
// keep track of progress
3141
count++;
@@ -38,11 +48,42 @@ export const initializeUnicodeData = async (contract: Contract) => {
3848

3949
// set each character
4050
const data = charToParameter(char);
51+
52+
// @ts-ignore
53+
batch.codes = [...batch.codes, char.code];
54+
// @ts-ignore
55+
batch.data = [...batch.data, data];
56+
57+
if (batch.codes.length < BATCH_SIZE) {
58+
continue;
59+
}
60+
4161
try {
42-
await contract.set(char.code, data);
62+
await contract.setBatch(batch.codes, batch.data);
63+
// reset
64+
batch = {
65+
codes: [],
66+
data: [],
67+
};
4368
} catch (err) {
44-
console.log("failed to set:", char);
69+
console.log(err);
70+
console.log("failed to set batch:", batch);
71+
failed = true;
4572
break;
4673
}
4774
}
75+
76+
// set final batch if it exists
77+
if (!batch.codes.length || failed) return;
78+
79+
try {
80+
await contract.setBatch(batch.codes, batch.data);
81+
// reset
82+
batch = {
83+
codes: [],
84+
data: [],
85+
};
86+
} catch (err) {
87+
console.log("failed to set final batch:", batch);
88+
}
4889
};

0 commit comments

Comments
 (0)