Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
1a14b811
Commit
1a14b811
authored
Oct 12, 2020
by
Karl Floersch
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add missing features to RingBuffer
parent
3ec7c358
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
115 additions
and
11 deletions
+115
-11
Lib_TimeboundRingBuffer.sol
...stic-ethereum/libraries/utils/Lib_TimeboundRingBuffer.sol
+38
-2
TestLib_TimeboundRingBuffer.sol
...acts/test-libraries/utils/TestLib_TimeboundRingBuffer.sol
+8
-0
Lib_TimeboundRingBuffer.spec.ts
...contracts/libraries/utils/Lib_TimeboundRingBuffer.spec.ts
+69
-9
No files found.
packages/contracts/contracts/optimistic-ethereum/libraries/utils/Lib_TimeboundRingBuffer.sol
View file @
1a14b811
...
...
@@ -50,6 +50,28 @@ library Lib_TimeboundRingBuffer {
_self.context = makeContext(uint32(length+1), _extraData);
}
function push2(
TimeboundRingBuffer storage _self,
bytes32 _ele1,
bytes32 _ele2,
bytes28 _extraData
)
internal
{
uint length = _getLength(_self.context);
uint maxSize = _self.maxSize;
if (length + 1 >= maxSize) {
if (block.timestamp < _self.firstElementTimestamp + _self.timeout) {
// Because this is a push2 we need to at least increment by 2
_self.maxSize += _self.maxSizeIncrementAmount > 1 ? _self.maxSizeIncrementAmount : 2;
maxSize = _self.maxSize;
}
}
_self.elements[length % maxSize] = _ele1;
_self.elements[(length + 1) % maxSize] = _ele2;
_self.context = makeContext(uint32(length+2), _extraData);
}
function makeContext(
uint32 _length,
bytes28 _extraData
...
...
@@ -60,7 +82,7 @@ library Lib_TimeboundRingBuffer {
bytes32
)
{
return bytes32(
bytes4
(_length));
return bytes32(
_extraData) | bytes32(uint256
(_length));
}
function getLength(
...
...
@@ -84,7 +106,21 @@ library Lib_TimeboundRingBuffer {
uint32
)
{
return uint32(bytes4(context));
bytes32 lengthMask = 0x00000000000000000000000000000000000000000000000000000000ffffffff;
return uint32(uint256(context & lengthMask));
}
function getExtraData(
TimeboundRingBuffer storage _self
)
internal
view
returns(
bytes28
)
{
bytes32 extraDataMask = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000;
return bytes28(_self.context & extraDataMask);
}
function get(
...
...
packages/contracts/contracts/test-libraries/utils/TestLib_TimeboundRingBuffer.sol
View file @
1a14b811
...
...
@@ -30,6 +30,10 @@ contract TestLib_TimeboundRingBuffer {
list.push(_ele, _extraData);
}
function push2(bytes32 _ele1, bytes32 _ele2, bytes28 _extraData) public {
list.push2(_ele1, _ele2, _extraData);
}
function get(uint32 index) public view returns(bytes32) {
return list.get(index);
}
...
...
@@ -38,6 +42,10 @@ contract TestLib_TimeboundRingBuffer {
return list.getLength();
}
function getExtraData() public view returns(bytes28) {
return list.getExtraData();
}
function getMaxSize() public view returns(uint32) {
return list.maxSize;
}
...
...
packages/contracts/test/contracts/libraries/utils/Lib_TimeboundRingBuffer.spec.ts
View file @
1a14b811
...
...
@@ -9,12 +9,10 @@ import { Contract, Signer } from 'ethers'
import
{
NON_NULL_BYTES32
,
makeHexString
,
fromHexString
,
getHexSlice
,
increaseEthTime
}
from
'
../../../helpers
'
const
numToBytes32
=
(
num
:
Number
)
=>
{
const
numToBytes32
=
(
num
:
Number
)
:
string
=>
{
if
(
num
<
0
||
num
>
255
)
{
throw
new
Error
(
'
Unsupported number.
'
)
}
...
...
@@ -22,7 +20,7 @@ const numToBytes32 = (num: Number) => {
return
'
0x
'
+
'
00
'
.
repeat
(
31
)
+
strNum
}
describe
.
only
(
'
Lib_TimeboundRingBuffer
'
,
()
=>
{
describe
(
'
Lib_TimeboundRingBuffer
'
,
()
=>
{
let
signer
:
Signer
before
(
async
()
=>
{
;[
signer
]
=
await
ethers
.
getSigners
()
...
...
@@ -32,7 +30,7 @@ describe.only('Lib_TimeboundRingBuffer', () => {
const
NON_NULL_BYTES28
=
makeHexString
(
'
01
'
,
28
)
describe
(
'
[0,1,2,3]
with no timeout
'
,
()
=>
{
describe
(
'
push
with no timeout
'
,
()
=>
{
beforeEach
(
async
()
=>
{
Lib_TimeboundRingBuffer
=
await
(
await
ethers
.
getContractFactory
(
'
TestLib_TimeboundRingBuffer
'
)
...
...
@@ -57,27 +55,48 @@ describe.only('Lib_TimeboundRingBuffer', () => {
})
})
describe
(
'
get()
'
,
()
=>
{
before
(
async
()
=>
{
Lib_TimeboundRingBuffer
=
await
(
await
ethers
.
getContractFactory
(
'
TestLib_TimeboundRingBuffer
'
)
).
deploy
(
2
,
1
,
10
_000
)
await
increaseEthTime
(
ethers
.
provider
,
20
_000
)
for
(
let
i
=
0
;
i
<
4
;
i
++
)
{
await
Lib_TimeboundRingBuffer
.
push
(
numToBytes32
(
i
),
NON_NULL_BYTES28
)
}
})
it
(
'
should revert if index is too old
'
,
async
()
=>
{
await
expect
(
Lib_TimeboundRingBuffer
.
get
(
0
)).
to
.
be
.
revertedWith
(
"
Index too old & has been overridden.
"
)
})
it
(
'
should revert if index is greater than length
'
,
async
()
=>
{
await
expect
(
Lib_TimeboundRingBuffer
.
get
(
5
)).
to
.
be
.
revertedWith
(
"
Index too large.
"
)
})
})
describe
(
'
push with timeout
'
,
()
=>
{
const
startSize
=
2
const
pushNum
=
(
num
:
Number
)
=>
Lib_TimeboundRingBuffer
.
push
(
numToBytes32
(
num
),
NON_NULL_BYTES28
)
beforeEach
(
async
()
=>
{
Lib_TimeboundRingBuffer
=
await
(
await
ethers
.
getContractFactory
(
'
TestLib_TimeboundRingBuffer
'
)
).
deploy
(
startSize
,
1
,
10
_000
)
for
(
let
i
=
0
;
i
<
startSize
;
i
++
)
{
await
Lib_TimeboundRingBuffer
.
push
(
numToBytes32
(
i
),
NON_NULL_BYTES28
)
await
pushNum
(
i
)
}
})
const
pushNum
=
(
num
:
Number
)
=>
Lib_TimeboundRingBuffer
.
push
(
numToBytes32
(
num
),
NON_NULL_BYTES28
)
const
pushJunk
=
()
=>
Lib_TimeboundRingBuffer
.
push
(
NON_NULL_BYTES32
,
NON_NULL_BYTES28
)
it
(
'
should push a single value which extends the array
'
,
async
()
=>
{
await
Lib_TimeboundRingBuffer
.
push
(
numToBytes32
(
2
),
NON_NULL_BYTES28
)
await
pushNum
(
2
)
const
increasedSize
=
startSize
+
1
expect
(
await
Lib_TimeboundRingBuffer
.
getMaxSize
()).
to
.
equal
(
increasedSize
)
await
increaseEthTime
(
ethers
.
provider
,
20
_000
)
await
Lib_TimeboundRingBuffer
.
push
(
numToBytes32
(
3
),
NON_NULL_BYTES28
)
await
pushNum
(
3
)
expect
(
await
Lib_TimeboundRingBuffer
.
getMaxSize
()).
to
.
equal
(
increasedSize
)
// Shouldn't increase the size this time
expect
(
await
Lib_TimeboundRingBuffer
.
get
(
2
)).
to
.
equal
(
numToBytes32
(
2
))
...
...
@@ -96,4 +115,45 @@ describe.only('Lib_TimeboundRingBuffer', () => {
expect
(
await
Lib_TimeboundRingBuffer
.
getMaxSize
()).
to
.
equal
(
increasedSize
)
})
})
describe
(
'
push2 with timeout
'
,
()
=>
{
const
startSize
=
2
const
push2Nums
=
(
num1
:
Number
,
num2
:
Number
)
=>
Lib_TimeboundRingBuffer
.
push2
(
numToBytes32
(
num1
),
numToBytes32
(
num2
),
NON_NULL_BYTES28
)
beforeEach
(
async
()
=>
{
Lib_TimeboundRingBuffer
=
await
(
await
ethers
.
getContractFactory
(
'
TestLib_TimeboundRingBuffer
'
)
).
deploy
(
startSize
,
1
,
10
_000
)
})
// it('should push two values which extends the array', async () => {
// })
it
(
'
should push a single value which extends the array
'
,
async
()
=>
{
await
push2Nums
(
0
,
1
)
await
push2Nums
(
2
,
3
)
const
increasedSize
=
startSize
+
2
expect
(
await
Lib_TimeboundRingBuffer
.
getMaxSize
()).
to
.
equal
(
increasedSize
)
await
increaseEthTime
(
ethers
.
provider
,
20
_000
)
await
push2Nums
(
4
,
5
)
expect
(
await
Lib_TimeboundRingBuffer
.
getMaxSize
()).
to
.
equal
(
increasedSize
)
// Shouldn't increase the size this time
for
(
let
i
=
2
;
i
<
6
;
i
++
)
{
expect
(
await
Lib_TimeboundRingBuffer
.
get
(
i
)).
to
.
equal
(
numToBytes32
(
i
))
}
})
})
describe
(
'
getExtraData
'
,
()
=>
{
beforeEach
(
async
()
=>
{
Lib_TimeboundRingBuffer
=
await
(
await
ethers
.
getContractFactory
(
'
TestLib_TimeboundRingBuffer
'
)
).
deploy
(
2
,
1
,
10
_000
)
})
it
(
'
should return the expected extra data
'
,
async
()
=>
{
await
Lib_TimeboundRingBuffer
.
push
(
NON_NULL_BYTES32
,
NON_NULL_BYTES28
)
expect
(
await
Lib_TimeboundRingBuffer
.
getExtraData
()).
to
.
equal
(
NON_NULL_BYTES28
)
})
})
})
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment