mirror of
https://github.com/QuilibriumNetwork/ceremonyclient.git
synced 2026-03-09 10:17:42 +08:00
Merge branch 'develop' into v2.0.4-p2
This commit is contained in:
commit
796f42e834
@ -37,7 +37,7 @@ var mergeCmd = &cobra.Command{
|
||||
panic(err)
|
||||
}
|
||||
|
||||
pub, err := privKey.GetPublic().Raw()
|
||||
pubKeyBytes, err := privKey.GetPublic().Raw()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -48,7 +48,7 @@ var mergeCmd = &cobra.Command{
|
||||
|
||||
addrBytes := addr.FillBytes(make([]byte, 32))
|
||||
|
||||
altAddr, err := poseidon.HashBytes([]byte(pub))
|
||||
altAddr, err := poseidon.HashBytes([]byte(pubKeyBytes))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -109,34 +109,20 @@ var mergeCmd = &cobra.Command{
|
||||
}
|
||||
}
|
||||
|
||||
// Create payload for merge operation
|
||||
payload := []byte("merge")
|
||||
for _, coinRef := range coinaddrs {
|
||||
payload = append(payload, coinRef.Address...)
|
||||
merge := &protobufs.MergeCoinRequest{
|
||||
Coins: coinaddrs,
|
||||
}
|
||||
|
||||
// Signing process
|
||||
sig, err := privKey.Sign(payload)
|
||||
if err != nil {
|
||||
if err := merge.SignED448(pubKeyBytes, privKey.Sign); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := merge.Validate(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Send merge request
|
||||
_, err = client.SendMessage(
|
||||
context.Background(),
|
||||
&protobufs.TokenRequest{
|
||||
Request: &protobufs.TokenRequest_Merge{
|
||||
Merge: &protobufs.MergeCoinRequest{
|
||||
Coins: coinaddrs,
|
||||
Signature: &protobufs.Ed448Signature{
|
||||
Signature: sig,
|
||||
PublicKey: &protobufs.Ed448PublicKey{
|
||||
KeyValue: pub,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
merge.TokenRequest(),
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
||||
@ -98,19 +98,19 @@ func publishMessage(
|
||||
filter []byte,
|
||||
message proto.Message,
|
||||
) error {
|
||||
any := &anypb.Any{}
|
||||
if err := any.MarshalFrom(message); err != nil {
|
||||
a := &anypb.Any{}
|
||||
if err := a.MarshalFrom(message); err != nil {
|
||||
return errors.Wrap(err, "publish message")
|
||||
}
|
||||
|
||||
any.TypeUrl = strings.Replace(
|
||||
any.TypeUrl,
|
||||
a.TypeUrl = strings.Replace(
|
||||
a.TypeUrl,
|
||||
"type.googleapis.com",
|
||||
"types.quilibrium.com",
|
||||
1,
|
||||
)
|
||||
|
||||
payload, err := proto.Marshal(any)
|
||||
payload, err := proto.Marshal(a)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "publish message")
|
||||
}
|
||||
|
||||
@ -29,7 +29,6 @@ var splitCmd = &cobra.Command{
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
payload := []byte("split")
|
||||
coinaddrHex, _ := strings.CutPrefix(args[0], "0x")
|
||||
coinaddr, err := hex.DecodeString(coinaddrHex)
|
||||
if err != nil {
|
||||
@ -38,7 +37,6 @@ var splitCmd = &cobra.Command{
|
||||
coin := &protobufs.CoinRef{
|
||||
Address: coinaddr,
|
||||
}
|
||||
payload = append(payload, coinaddr...)
|
||||
|
||||
conversionFactor, _ := new(big.Int).SetString("1DCD65000", 16)
|
||||
amounts := [][]byte{}
|
||||
@ -51,7 +49,6 @@ var splitCmd = &cobra.Command{
|
||||
amount = amount.Mul(decimal.NewFromBigInt(conversionFactor, 0))
|
||||
amountBytes := amount.BigInt().FillBytes(make([]byte, 32))
|
||||
amounts = append(amounts, amountBytes)
|
||||
payload = append(payload, amountBytes...)
|
||||
}
|
||||
|
||||
conn, err := GetGRPCClient()
|
||||
@ -61,37 +58,29 @@ var splitCmd = &cobra.Command{
|
||||
defer conn.Close()
|
||||
|
||||
client := protobufs.NewNodeServiceClient(conn)
|
||||
key, err := GetPrivKeyFromConfig(NodeConfig)
|
||||
privKey, err := GetPrivKeyFromConfig(NodeConfig)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
pubKeyBytes, err := privKey.GetPublic().Raw()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
sig, err := key.Sign(payload)
|
||||
if err != nil {
|
||||
split := &protobufs.SplitCoinRequest{
|
||||
OfCoin: coin,
|
||||
Amounts: amounts,
|
||||
}
|
||||
if err := split.SignED448(pubKeyBytes, privKey.Sign); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
pub, err := key.GetPublic().Raw()
|
||||
if err != nil {
|
||||
if err := split.Validate(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
_, err = client.SendMessage(
|
||||
context.Background(),
|
||||
&protobufs.TokenRequest{
|
||||
Request: &protobufs.TokenRequest_Split{
|
||||
Split: &protobufs.SplitCoinRequest{
|
||||
OfCoin: coin,
|
||||
Amounts: amounts,
|
||||
Signature: &protobufs.Ed448Signature{
|
||||
Signature: sig,
|
||||
PublicKey: &protobufs.Ed448PublicKey{
|
||||
KeyValue: pub,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
split.TokenRequest(),
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
||||
@ -31,13 +31,16 @@ var transferCmd = &cobra.Command{
|
||||
defer conn.Close()
|
||||
|
||||
client := protobufs.NewNodeServiceClient(conn)
|
||||
key, err := GetPrivKeyFromConfig(NodeConfig)
|
||||
privKey, err := GetPrivKeyFromConfig(NodeConfig)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
pubKeyBytes, err := privKey.GetPublic().Raw()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var coinaddr *protobufs.CoinRef
|
||||
payload := []byte("transfer")
|
||||
toaddr := []byte{}
|
||||
for i, arg := range args {
|
||||
addrHex, _ := strings.CutPrefix(arg, "0x")
|
||||
@ -53,42 +56,28 @@ var transferCmd = &cobra.Command{
|
||||
coinaddr = &protobufs.CoinRef{
|
||||
Address: addr,
|
||||
}
|
||||
payload = append(payload, addr...)
|
||||
}
|
||||
payload = append(payload, toaddr...)
|
||||
|
||||
sig, err := key.Sign(payload)
|
||||
if err != nil {
|
||||
transfer := &protobufs.TransferCoinRequest{
|
||||
OfCoin: coinaddr,
|
||||
ToAccount: &protobufs.AccountRef{
|
||||
Account: &protobufs.AccountRef_ImplicitAccount{
|
||||
ImplicitAccount: &protobufs.ImplicitAccount{
|
||||
Address: toaddr,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
if err := transfer.SignED448(pubKeyBytes, privKey.Sign); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
pub, err := key.GetPublic().Raw()
|
||||
if err != nil {
|
||||
if err := transfer.Validate(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
_, err = client.SendMessage(
|
||||
context.Background(),
|
||||
&protobufs.TokenRequest{
|
||||
Request: &protobufs.TokenRequest_Transfer{
|
||||
Transfer: &protobufs.TransferCoinRequest{
|
||||
OfCoin: coinaddr,
|
||||
ToAccount: &protobufs.AccountRef{
|
||||
Account: &protobufs.AccountRef_ImplicitAccount{
|
||||
ImplicitAccount: &protobufs.ImplicitAccount{
|
||||
Address: toaddr,
|
||||
},
|
||||
},
|
||||
},
|
||||
Signature: &protobufs.Ed448Signature{
|
||||
Signature: sig,
|
||||
PublicKey: &protobufs.Ed448PublicKey{
|
||||
KeyValue: pub,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
transfer.TokenRequest(),
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
module source.quilibrium.com/quilibrium/monorepo/client
|
||||
|
||||
go 1.21
|
||||
go 1.22
|
||||
|
||||
toolchain go1.22.1
|
||||
toolchain go1.22.5
|
||||
|
||||
replace source.quilibrium.com/quilibrium/monorepo/nekryptology => ../nekryptology
|
||||
|
||||
@ -14,6 +14,8 @@ replace github.com/multiformats/go-multiaddr => ../go-multiaddr
|
||||
|
||||
replace github.com/multiformats/go-multiaddr-dns => ../go-multiaddr-dns
|
||||
|
||||
replace github.com/libp2p/go-buffer-pool => ../go-buffer-pool
|
||||
|
||||
replace github.com/libp2p/go-libp2p => ../go-libp2p
|
||||
|
||||
replace github.com/libp2p/go-libp2p-kad-dht => ../go-libp2p-kad-dht
|
||||
|
||||
@ -263,8 +263,6 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c=
|
||||
github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8=
|
||||
github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8=
|
||||
github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg=
|
||||
github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c=
|
||||
github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic=
|
||||
github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM=
|
||||
|
||||
18
go-buffer-pool/.github/workflows/go-check.yml
vendored
Normal file
18
go-buffer-pool/.github/workflows/go-check.yml
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
name: Go Checks
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches: ["master"]
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event_name == 'push' && github.sha || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
go-check:
|
||||
uses: ipdxco/unified-github-workflows/.github/workflows/go-check.yml@v1.0
|
||||
20
go-buffer-pool/.github/workflows/go-test.yml
vendored
Normal file
20
go-buffer-pool/.github/workflows/go-test.yml
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
name: Go Test
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches: ["master"]
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event_name == 'push' && github.sha || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
go-test:
|
||||
uses: ipdxco/unified-github-workflows/.github/workflows/go-test.yml@v1.0
|
||||
secrets:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
19
go-buffer-pool/.github/workflows/release-check.yml
vendored
Normal file
19
go-buffer-pool/.github/workflows/release-check.yml
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
name: Release Checker
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
paths: [ 'version.json' ]
|
||||
types: [ opened, synchronize, reopened, labeled, unlabeled ]
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
release-check:
|
||||
uses: ipdxco/unified-github-workflows/.github/workflows/release-check.yml@v1.0
|
||||
17
go-buffer-pool/.github/workflows/releaser.yml
vendored
Normal file
17
go-buffer-pool/.github/workflows/releaser.yml
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
name: Releaser
|
||||
|
||||
on:
|
||||
push:
|
||||
paths: [ 'version.json' ]
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.sha }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
releaser:
|
||||
uses: ipdxco/unified-github-workflows/.github/workflows/releaser.yml@v1.0
|
||||
13
go-buffer-pool/.github/workflows/stale.yml
vendored
Normal file
13
go-buffer-pool/.github/workflows/stale.yml
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
name: Close and mark stale issue
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
uses: pl-strflt/.github/.github/workflows/reusable-stale-issue.yml@v0.3
|
||||
18
go-buffer-pool/.github/workflows/tagpush.yml
vendored
Normal file
18
go-buffer-pool/.github/workflows/tagpush.yml
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
name: Tag Push Checker
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- v*
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
releaser:
|
||||
uses: ipdxco/unified-github-workflows/.github/workflows/tagpush.yml@v1.0
|
||||
21
go-buffer-pool/LICENSE
Normal file
21
go-buffer-pool/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Juan Batiz-Benet
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
29
go-buffer-pool/LICENSE-BSD
Normal file
29
go-buffer-pool/LICENSE-BSD
Normal file
@ -0,0 +1,29 @@
|
||||
### Applies to buffer.go and buffer_test.go ###
|
||||
|
||||
Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
56
go-buffer-pool/README.md
Normal file
56
go-buffer-pool/README.md
Normal file
@ -0,0 +1,56 @@
|
||||
go-buffer-pool
|
||||
==================
|
||||
|
||||
[](https://protocol.ai)
|
||||
[](https://libp2p.io/)
|
||||
[](https://webchat.freenode.net/?channels=%23libp2p)
|
||||
[](https://codecov.io/gh/libp2p/go-buffer-pool)
|
||||
[](https://travis-ci.org/libp2p/go-buffer-pool)
|
||||
[](https://discuss.libp2p.io)
|
||||
|
||||
> A variable size buffer pool for go.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [About](#about)
|
||||
- [Advantages over GC](#advantages-over-gc)
|
||||
- [Disadvantages over GC:](#disadvantages-over-gc)
|
||||
- [Contribute](#contribute)
|
||||
- [License](#license)
|
||||
|
||||
## About
|
||||
|
||||
This library provides:
|
||||
|
||||
1. `BufferPool`: A pool for re-using byte slices of varied sizes. This pool will always return a slice with at least the size requested and a capacity up to the next power of two. Each size class is pooled independently which makes the `BufferPool` more space efficient than a plain `sync.Pool` when used in situations where data size may vary over an arbitrary range.
|
||||
2. `Buffer`: a buffer compatible with `bytes.Buffer` but backed by a `BufferPool`. Unlike `bytes.Buffer`, `Buffer` will automatically "shrink" on read, using the buffer pool to avoid causing too much work for the allocator. This is primarily useful for long lived buffers that usually sit empty.
|
||||
|
||||
### Advantages over GC
|
||||
|
||||
* Reduces Memory Usage:
|
||||
* We don't have to wait for a GC to run before we can reuse memory. This is essential if you're repeatedly allocating large short-lived buffers.
|
||||
|
||||
* Reduces CPU usage:
|
||||
* It takes some load off of the GC (due to buffer reuse).
|
||||
* We don't have to zero buffers (fewer wasteful memory writes).
|
||||
|
||||
### Disadvantages over GC:
|
||||
|
||||
* Can leak memory contents. Unlike the go GC, we *don't* zero memory.
|
||||
* All buffers have a capacity of a power of 2. This is fine if you either expect these buffers to be temporary or you need buffers of this size.
|
||||
* Requires that buffers be explicitly put back into the pool. This can lead to race conditions and memory corruption if the buffer is released while it's still in use.
|
||||
|
||||
## Contribute
|
||||
|
||||
PRs are welcome!
|
||||
|
||||
Small note: If editing the Readme, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification.
|
||||
|
||||
## License
|
||||
|
||||
MIT © Protocol Labs
|
||||
BSD © The Go Authors
|
||||
|
||||
---
|
||||
|
||||
The last gx published version of this module was: 0.1.3: QmQDvJoB6aJWN3sjr3xsgXqKCXf4jU5zdMXpDMsBkYVNqa
|
||||
302
go-buffer-pool/buffer.go
Normal file
302
go-buffer-pool/buffer.go
Normal file
@ -0,0 +1,302 @@
|
||||
// This is a derivitive work of Go's bytes.Buffer implementation.
|
||||
//
|
||||
// Originally copyright 2009 The Go Authors. All rights reserved.
|
||||
//
|
||||
// Modifications copyright 2018 Steven Allen. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by both a BSD-style and an MIT-style
|
||||
// license that can be found in the LICENSE_BSD and LICENSE files.
|
||||
|
||||
package pool
|
||||
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
// Buffer is a buffer like bytes.Buffer that:
|
||||
//
|
||||
// 1. Uses a buffer pool.
|
||||
// 2. Frees memory on read.
|
||||
//
|
||||
// If you only have a few buffers and read/write at a steady rate, *don't* use
|
||||
// this package, it'll be slower.
|
||||
//
|
||||
// However:
|
||||
//
|
||||
// 1. If you frequently create/destroy buffers, this implementation will be
|
||||
// significantly nicer to the allocator.
|
||||
// 2. If you have many buffers with bursty traffic, this implementation will use
|
||||
// significantly less memory.
|
||||
type Buffer struct {
|
||||
// Pool is the buffer pool to use. If nil, this Buffer will use the
|
||||
// global buffer pool.
|
||||
Pool *BufferPool
|
||||
|
||||
buf []byte
|
||||
rOff int
|
||||
|
||||
// Preallocated slice for samll reads/writes.
|
||||
// This is *really* important for performance and only costs 8 words.
|
||||
bootstrap [64]byte
|
||||
}
|
||||
|
||||
// NewBuffer constructs a new buffer initialized to `buf`.
|
||||
// Unlike `bytes.Buffer`, we *copy* the buffer but don't reuse it (to ensure
|
||||
// that we *only* use buffers from the pool).
|
||||
func NewBuffer(buf []byte) *Buffer {
|
||||
b := new(Buffer)
|
||||
if len(buf) > 0 {
|
||||
b.buf = b.getBuf(len(buf))
|
||||
copy(b.buf, buf)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// NewBufferString is identical to NewBuffer *except* that it allows one to
|
||||
// initialize the buffer from a string (without having to allocate an
|
||||
// intermediate bytes slice).
|
||||
func NewBufferString(buf string) *Buffer {
|
||||
b := new(Buffer)
|
||||
if len(buf) > 0 {
|
||||
b.buf = b.getBuf(len(buf))
|
||||
copy(b.buf, buf)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *Buffer) grow(n int) int {
|
||||
wOff := len(b.buf)
|
||||
bCap := cap(b.buf)
|
||||
|
||||
if bCap >= wOff+n {
|
||||
b.buf = b.buf[:wOff+n]
|
||||
return wOff
|
||||
}
|
||||
|
||||
bSize := b.Len()
|
||||
|
||||
minCap := 2*bSize + n
|
||||
|
||||
// Slide if cap >= minCap.
|
||||
// Reallocate otherwise.
|
||||
if bCap >= minCap {
|
||||
copy(b.buf, b.buf[b.rOff:])
|
||||
} else {
|
||||
// Needs new buffer.
|
||||
newBuf := b.getBuf(minCap)
|
||||
copy(newBuf, b.buf[b.rOff:])
|
||||
b.returnBuf()
|
||||
b.buf = newBuf
|
||||
}
|
||||
|
||||
b.rOff = 0
|
||||
b.buf = b.buf[:bSize+n]
|
||||
return bSize
|
||||
}
|
||||
|
||||
func (b *Buffer) getPool() *BufferPool {
|
||||
if b.Pool == nil {
|
||||
return GlobalPool
|
||||
}
|
||||
return b.Pool
|
||||
}
|
||||
|
||||
func (b *Buffer) returnBuf() {
|
||||
if cap(b.buf) > len(b.bootstrap) {
|
||||
b.getPool().Put(b.buf)
|
||||
}
|
||||
b.buf = nil
|
||||
}
|
||||
|
||||
func (b *Buffer) getBuf(n int) []byte {
|
||||
if n <= len(b.bootstrap) {
|
||||
return b.bootstrap[:n]
|
||||
}
|
||||
return b.getPool().Get(n)
|
||||
}
|
||||
|
||||
// Len returns the number of bytes that can be read from this buffer.
|
||||
func (b *Buffer) Len() int {
|
||||
return len(b.buf) - b.rOff
|
||||
}
|
||||
|
||||
// Cap returns the current capacity of the buffer.
|
||||
//
|
||||
// Note: Buffer *may* re-allocate when writing (or growing by) `n` bytes even if
|
||||
// `Cap() < Len() + n` to avoid excessive copying.
|
||||
func (b *Buffer) Cap() int {
|
||||
return cap(b.buf)
|
||||
}
|
||||
|
||||
// Bytes returns the slice of bytes currently buffered in the Buffer.
|
||||
//
|
||||
// The buffer returned by Bytes is valid until the next call grow, truncate,
|
||||
// read, or write. Really, just don't touch the Buffer until you're done with
|
||||
// the return value of this function.
|
||||
func (b *Buffer) Bytes() []byte {
|
||||
return b.buf[b.rOff:]
|
||||
}
|
||||
|
||||
// String returns the string representation of the buffer.
|
||||
//
|
||||
// It returns `<nil>` the buffer is a nil pointer.
|
||||
func (b *Buffer) String() string {
|
||||
if b == nil {
|
||||
return "<nil>"
|
||||
}
|
||||
return string(b.buf[b.rOff:])
|
||||
}
|
||||
|
||||
// WriteString writes a string to the buffer.
|
||||
//
|
||||
// This function is identical to Write except that it allows one to write a
|
||||
// string directly without allocating an intermediate byte slice.
|
||||
func (b *Buffer) WriteString(buf string) (int, error) {
|
||||
wOff := b.grow(len(buf))
|
||||
return copy(b.buf[wOff:], buf), nil
|
||||
}
|
||||
|
||||
// Truncate truncates the Buffer.
|
||||
//
|
||||
// Panics if `n > b.Len()`.
|
||||
//
|
||||
// This function may free memory by shrinking the internal buffer.
|
||||
func (b *Buffer) Truncate(n int) {
|
||||
if n < 0 || n > b.Len() {
|
||||
panic("truncation out of range")
|
||||
}
|
||||
b.buf = b.buf[:b.rOff+n]
|
||||
b.shrink()
|
||||
}
|
||||
|
||||
// Reset is equivalent to Truncate(0).
|
||||
func (b *Buffer) Reset() {
|
||||
b.returnBuf()
|
||||
b.rOff = 0
|
||||
}
|
||||
|
||||
// ReadByte reads a single byte from the Buffer.
|
||||
func (b *Buffer) ReadByte() (byte, error) {
|
||||
if b.rOff >= len(b.buf) {
|
||||
return 0, io.EOF
|
||||
}
|
||||
c := b.buf[b.rOff]
|
||||
b.rOff++
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// WriteByte writes a single byte to the Buffer.
|
||||
func (b *Buffer) WriteByte(c byte) error {
|
||||
wOff := b.grow(1)
|
||||
b.buf[wOff] = c
|
||||
return nil
|
||||
}
|
||||
|
||||
// Grow grows the internal buffer such that `n` bytes can be written without
|
||||
// reallocating.
|
||||
func (b *Buffer) Grow(n int) {
|
||||
wOff := b.grow(n)
|
||||
b.buf = b.buf[:wOff]
|
||||
}
|
||||
|
||||
// Next is an alternative to `Read` that returns a byte slice instead of taking
|
||||
// one.
|
||||
//
|
||||
// The returned byte slice is valid until the next read, write, grow, or
|
||||
// truncate.
|
||||
func (b *Buffer) Next(n int) []byte {
|
||||
m := b.Len()
|
||||
if m < n {
|
||||
n = m
|
||||
}
|
||||
data := b.buf[b.rOff : b.rOff+n]
|
||||
b.rOff += n
|
||||
return data
|
||||
}
|
||||
|
||||
// Write writes the byte slice to the buffer.
|
||||
func (b *Buffer) Write(buf []byte) (int, error) {
|
||||
wOff := b.grow(len(buf))
|
||||
return copy(b.buf[wOff:], buf), nil
|
||||
}
|
||||
|
||||
// WriteTo copies from the buffer into the given writer until the buffer is
|
||||
// empty.
|
||||
func (b *Buffer) WriteTo(w io.Writer) (int64, error) {
|
||||
if b.rOff < len(b.buf) {
|
||||
n, err := w.Write(b.buf[b.rOff:])
|
||||
b.rOff += n
|
||||
if b.rOff > len(b.buf) {
|
||||
panic("invalid write count")
|
||||
}
|
||||
b.shrink()
|
||||
return int64(n), err
|
||||
}
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
// MinRead is the minimum slice size passed to a Read call by
|
||||
// Buffer.ReadFrom. As long as the Buffer has at least MinRead bytes beyond
|
||||
// what is required to hold the contents of r, ReadFrom will not grow the
|
||||
// underlying buffer.
|
||||
const MinRead = 512
|
||||
|
||||
// ReadFrom reads from the given reader into the buffer.
|
||||
func (b *Buffer) ReadFrom(r io.Reader) (int64, error) {
|
||||
n := int64(0)
|
||||
for {
|
||||
wOff := b.grow(MinRead)
|
||||
// Use *entire* buffer.
|
||||
b.buf = b.buf[:cap(b.buf)]
|
||||
|
||||
read, err := r.Read(b.buf[wOff:])
|
||||
b.buf = b.buf[:wOff+read]
|
||||
n += int64(read)
|
||||
switch err {
|
||||
case nil:
|
||||
case io.EOF:
|
||||
err = nil
|
||||
fallthrough
|
||||
default:
|
||||
b.shrink()
|
||||
return n, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Read reads at most `len(buf)` bytes from the internal buffer into the given
|
||||
// buffer.
|
||||
func (b *Buffer) Read(buf []byte) (int, error) {
|
||||
if len(buf) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
if b.rOff >= len(b.buf) {
|
||||
return 0, io.EOF
|
||||
}
|
||||
n := copy(buf, b.buf[b.rOff:])
|
||||
b.rOff += n
|
||||
b.shrink()
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func (b *Buffer) shrink() {
|
||||
c := b.Cap()
|
||||
// Either nil or bootstrap.
|
||||
if c <= len(b.bootstrap) {
|
||||
return
|
||||
}
|
||||
|
||||
l := b.Len()
|
||||
if l == 0 {
|
||||
// Shortcut if empty.
|
||||
b.returnBuf()
|
||||
b.rOff = 0
|
||||
} else if l*8 < c {
|
||||
// Only shrink when capacity > 8x length. Avoids shrinking too aggressively.
|
||||
newBuf := b.getBuf(l)
|
||||
copy(newBuf, b.buf[b.rOff:])
|
||||
b.returnBuf()
|
||||
b.rOff = 0
|
||||
b.buf = newBuf[:l]
|
||||
}
|
||||
}
|
||||
400
go-buffer-pool/buffer_test.go
Normal file
400
go-buffer-pool/buffer_test.go
Normal file
@ -0,0 +1,400 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Modified by stebalien, 2018
|
||||
|
||||
package pool
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"math/rand"
|
||||
"runtime"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const N = 10000 // make this bigger for a larger (and slower) test
|
||||
var data string // test data for write tests
|
||||
var testBytes []byte // test data; same as data but as a slice.
|
||||
|
||||
func init() {
|
||||
testBytes = make([]byte, N)
|
||||
for i := 0; i < N; i++ {
|
||||
testBytes[i] = 'a' + byte(i%26)
|
||||
}
|
||||
data = string(testBytes)
|
||||
}
|
||||
|
||||
// Verify that contents of buf match the string s.
|
||||
func check(t *testing.T, testname string, buf *Buffer, s string) {
|
||||
bytes := buf.Bytes()
|
||||
str := buf.String()
|
||||
if buf.Len() != len(bytes) {
|
||||
t.Errorf("%s: buf.Len() == %d, len(buf.Bytes()) == %d", testname, buf.Len(), len(bytes))
|
||||
}
|
||||
|
||||
if buf.Len() != len(str) {
|
||||
t.Errorf("%s: buf.Len() == %d, len(buf.String()) == %d", testname, buf.Len(), len(str))
|
||||
}
|
||||
|
||||
if buf.Len() != len(s) {
|
||||
t.Errorf("%s: buf.Len() == %d, len(s) == %d", testname, buf.Len(), len(s))
|
||||
}
|
||||
|
||||
if string(bytes) != s {
|
||||
t.Errorf("%s: string(buf.Bytes()) == %q, s == %q", testname, string(bytes), s)
|
||||
}
|
||||
}
|
||||
|
||||
// Fill buf through n writes of string fus.
|
||||
// The initial contents of buf corresponds to the string s;
|
||||
// the result is the final contents of buf returned as a string.
|
||||
func fillString(t *testing.T, testname string, buf *Buffer, s string, n int, fus string) string {
|
||||
check(t, testname+" (fill 1)", buf, s)
|
||||
for ; n > 0; n-- {
|
||||
m, err := buf.WriteString(fus)
|
||||
if m != len(fus) {
|
||||
t.Errorf(testname+" (fill 2): m == %d, expected %d", m, len(fus))
|
||||
}
|
||||
if err != nil {
|
||||
t.Errorf(testname+" (fill 3): err should always be nil, found err == %s", err)
|
||||
}
|
||||
s += fus
|
||||
check(t, testname+" (fill 4)", buf, s)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// Fill buf through n writes of byte slice fub.
|
||||
// The initial contents of buf corresponds to the string s;
|
||||
// the result is the final contents of buf returned as a string.
|
||||
func fillBytes(t *testing.T, testname string, buf *Buffer, s string, n int, fub []byte) string {
|
||||
check(t, testname+" (fill 1)", buf, s)
|
||||
for ; n > 0; n-- {
|
||||
m, err := buf.Write(fub)
|
||||
if m != len(fub) {
|
||||
t.Errorf(testname+" (fill 2): m == %d, expected %d", m, len(fub))
|
||||
}
|
||||
if err != nil {
|
||||
t.Errorf(testname+" (fill 3): err should always be nil, found err == %s", err)
|
||||
}
|
||||
s += string(fub)
|
||||
check(t, testname+" (fill 4)", buf, s)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func TestNewBuffer(t *testing.T) {
|
||||
buf := NewBuffer(testBytes)
|
||||
check(t, "NewBuffer", buf, data)
|
||||
}
|
||||
|
||||
func TestNewBufferString(t *testing.T) {
|
||||
buf := NewBufferString(data)
|
||||
check(t, "NewBufferString", buf, data)
|
||||
}
|
||||
|
||||
// Empty buf through repeated reads into fub.
|
||||
// The initial contents of buf corresponds to the string s.
|
||||
func empty(t *testing.T, testname string, buf *Buffer, s string, fub []byte) {
|
||||
check(t, testname+" (empty 1)", buf, s)
|
||||
|
||||
for {
|
||||
n, err := buf.Read(fub)
|
||||
if n == 0 {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
t.Errorf(testname+" (empty 2): err should always be nil, found err == %s", err)
|
||||
}
|
||||
s = s[n:]
|
||||
check(t, testname+" (empty 3)", buf, s)
|
||||
}
|
||||
|
||||
check(t, testname+" (empty 4)", buf, "")
|
||||
}
|
||||
|
||||
func TestBasicOperations(t *testing.T) {
|
||||
var buf Buffer
|
||||
|
||||
for i := 0; i < 5; i++ {
|
||||
check(t, "TestBasicOperations (1)", &buf, "")
|
||||
|
||||
buf.Reset()
|
||||
check(t, "TestBasicOperations (2)", &buf, "")
|
||||
|
||||
buf.Truncate(0)
|
||||
check(t, "TestBasicOperations (3)", &buf, "")
|
||||
|
||||
n, err := buf.Write([]byte(data[0:1]))
|
||||
if n != 1 {
|
||||
t.Errorf("wrote 1 byte, but n == %d", n)
|
||||
}
|
||||
if err != nil {
|
||||
t.Errorf("err should always be nil, but err == %s", err)
|
||||
}
|
||||
check(t, "TestBasicOperations (4)", &buf, "a")
|
||||
|
||||
buf.WriteByte(data[1])
|
||||
check(t, "TestBasicOperations (5)", &buf, "ab")
|
||||
|
||||
n, err = buf.Write([]byte(data[2:26]))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if n != 24 {
|
||||
t.Errorf("wrote 25 bytes, but n == %d", n)
|
||||
}
|
||||
check(t, "TestBasicOperations (6)", &buf, string(data[0:26]))
|
||||
|
||||
buf.Truncate(26)
|
||||
check(t, "TestBasicOperations (7)", &buf, string(data[0:26]))
|
||||
|
||||
buf.Truncate(20)
|
||||
check(t, "TestBasicOperations (8)", &buf, string(data[0:20]))
|
||||
|
||||
empty(t, "TestBasicOperations (9)", &buf, string(data[0:20]), make([]byte, 5))
|
||||
empty(t, "TestBasicOperations (10)", &buf, "", make([]byte, 100))
|
||||
|
||||
buf.WriteByte(data[1])
|
||||
c, err := buf.ReadByte()
|
||||
if err != nil {
|
||||
t.Error("ReadByte unexpected eof")
|
||||
}
|
||||
if c != data[1] {
|
||||
t.Errorf("ReadByte wrong value c=%v", c)
|
||||
}
|
||||
if _, err = buf.ReadByte(); err == nil {
|
||||
t.Error("ReadByte unexpected not eof")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestLargeStringWrites(t *testing.T) {
|
||||
var buf Buffer
|
||||
limit := 30
|
||||
if testing.Short() {
|
||||
limit = 9
|
||||
}
|
||||
for i := 3; i < limit; i += 3 {
|
||||
s := fillString(t, "TestLargeWrites (1)", &buf, "", 5, data)
|
||||
empty(t, "TestLargeStringWrites (2)", &buf, s, make([]byte, len(data)/i))
|
||||
}
|
||||
check(t, "TestLargeStringWrites (3)", &buf, "")
|
||||
}
|
||||
|
||||
func TestLargeByteWrites(t *testing.T) {
|
||||
var buf Buffer
|
||||
limit := 30
|
||||
if testing.Short() {
|
||||
limit = 9
|
||||
}
|
||||
for i := 3; i < limit; i += 3 {
|
||||
s := fillBytes(t, "TestLargeWrites (1)", &buf, "", 5, testBytes)
|
||||
empty(t, "TestLargeByteWrites (2)", &buf, s, make([]byte, len(data)/i))
|
||||
}
|
||||
check(t, "TestLargeByteWrites (3)", &buf, "")
|
||||
}
|
||||
|
||||
func TestLargeStringReads(t *testing.T) {
|
||||
var buf Buffer
|
||||
for i := 3; i < 30; i += 3 {
|
||||
s := fillString(t, "TestLargeReads (1)", &buf, "", 5, data[0:len(data)/i])
|
||||
empty(t, "TestLargeReads (2)", &buf, s, make([]byte, len(data)))
|
||||
}
|
||||
check(t, "TestLargeStringReads (3)", &buf, "")
|
||||
}
|
||||
|
||||
func TestLargeByteReads(t *testing.T) {
|
||||
var buf Buffer
|
||||
for i := 3; i < 30; i += 3 {
|
||||
s := fillBytes(t, "TestLargeReads (1)", &buf, "", 5, testBytes[0:len(testBytes)/i])
|
||||
empty(t, "TestLargeReads (2)", &buf, s, make([]byte, len(data)))
|
||||
}
|
||||
check(t, "TestLargeByteReads (3)", &buf, "")
|
||||
}
|
||||
|
||||
func TestMixedReadsAndWrites(t *testing.T) {
|
||||
var buf Buffer
|
||||
s := ""
|
||||
for i := 0; i < 50; i++ {
|
||||
wlen := rand.Intn(len(data))
|
||||
if i%2 == 0 {
|
||||
s = fillString(t, "TestMixedReadsAndWrites (1)", &buf, s, 1, data[0:wlen])
|
||||
} else {
|
||||
s = fillBytes(t, "TestMixedReadsAndWrites (1)", &buf, s, 1, testBytes[0:wlen])
|
||||
}
|
||||
|
||||
rlen := rand.Intn(len(data))
|
||||
fub := make([]byte, rlen)
|
||||
n, _ := buf.Read(fub)
|
||||
s = s[n:]
|
||||
}
|
||||
empty(t, "TestMixedReadsAndWrites (2)", &buf, s, make([]byte, buf.Len()))
|
||||
}
|
||||
|
||||
func TestNil(t *testing.T) {
|
||||
var b *Buffer
|
||||
if b.String() != "<nil>" {
|
||||
t.Errorf("expected <nil>; got %q", b.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadFrom(t *testing.T) {
|
||||
var buf Buffer
|
||||
for i := 3; i < 30; i += 3 {
|
||||
s := fillBytes(t, "TestReadFrom (1)", &buf, "", 5, testBytes[0:len(testBytes)/i])
|
||||
var b Buffer
|
||||
b.ReadFrom(&buf)
|
||||
empty(t, "TestReadFrom (2)", &b, s, make([]byte, len(data)))
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriteTo(t *testing.T) {
|
||||
var buf Buffer
|
||||
for i := 3; i < 30; i += 3 {
|
||||
s := fillBytes(t, "TestWriteTo (1)", &buf, "", 5, testBytes[0:len(testBytes)/i])
|
||||
var b Buffer
|
||||
buf.WriteTo(&b)
|
||||
empty(t, "TestWriteTo (2)", &b, s, make([]byte, len(data)))
|
||||
}
|
||||
}
|
||||
|
||||
func TestNext(t *testing.T) {
|
||||
b := []byte{0, 1, 2, 3, 4}
|
||||
tmp := make([]byte, 5)
|
||||
for i := 0; i <= 5; i++ {
|
||||
for j := i; j <= 5; j++ {
|
||||
for k := 0; k <= 6; k++ {
|
||||
// 0 <= i <= j <= 5; 0 <= k <= 6
|
||||
// Check that if we start with a buffer
|
||||
// of length j at offset i and ask for
|
||||
// Next(k), we get the right bytes.
|
||||
buf := NewBuffer(b[0:j])
|
||||
n, _ := buf.Read(tmp[0:i])
|
||||
if n != i {
|
||||
t.Fatalf("Read %d returned %d", i, n)
|
||||
}
|
||||
bb := buf.Next(k)
|
||||
want := k
|
||||
if want > j-i {
|
||||
want = j - i
|
||||
}
|
||||
if len(bb) != want {
|
||||
t.Fatalf("in %d,%d: len(Next(%d)) == %d", i, j, k, len(bb))
|
||||
}
|
||||
for l, v := range bb {
|
||||
if v != byte(l+i) {
|
||||
t.Fatalf("in %d,%d: Next(%d)[%d] = %d, want %d", i, j, k, l, v, l+i)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGrow(t *testing.T) {
|
||||
x := []byte{'x'}
|
||||
y := []byte{'y'}
|
||||
tmp := make([]byte, 72)
|
||||
for _, startLen := range []int{0, 100, 1000, 10000, 100000} {
|
||||
xBytes := bytes.Repeat(x, startLen)
|
||||
for _, growLen := range []int{0, 100, 1000, 10000, 100000} {
|
||||
buf := NewBuffer(xBytes)
|
||||
// If we read, this affects buf.off, which is good to test.
|
||||
readBytes, _ := buf.Read(tmp)
|
||||
buf.Grow(growLen)
|
||||
yBytes := bytes.Repeat(y, growLen)
|
||||
// Check no allocation occurs in write, as long as we're single-threaded.
|
||||
var m1, m2 runtime.MemStats
|
||||
runtime.ReadMemStats(&m1)
|
||||
buf.Write(yBytes)
|
||||
runtime.ReadMemStats(&m2)
|
||||
if runtime.GOMAXPROCS(-1) == 1 && m1.Mallocs != m2.Mallocs {
|
||||
t.Errorf("allocation occurred during write")
|
||||
}
|
||||
// Check that buffer has correct data.
|
||||
if !bytes.Equal(buf.Bytes()[0:startLen-readBytes], xBytes[readBytes:]) {
|
||||
t.Errorf("bad initial data at %d %d", startLen, growLen)
|
||||
}
|
||||
if !bytes.Equal(buf.Bytes()[startLen-readBytes:startLen-readBytes+growLen], yBytes) {
|
||||
t.Errorf("bad written data at %d %d", startLen, growLen)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Was a bug: used to give EOF reading empty slice at EOF.
|
||||
func TestReadEmptyAtEOF(t *testing.T) {
|
||||
b := new(Buffer)
|
||||
slice := make([]byte, 0)
|
||||
n, err := b.Read(slice)
|
||||
if err != nil {
|
||||
t.Errorf("read error: %v", err)
|
||||
}
|
||||
if n != 0 {
|
||||
t.Errorf("wrong count; got %d want 0", n)
|
||||
}
|
||||
}
|
||||
|
||||
// Tests that we occasionally compact. Issue 5154.
|
||||
func TestBufferGrowth(t *testing.T) {
|
||||
var b Buffer
|
||||
buf := make([]byte, 1024)
|
||||
b.Write(buf[0:1])
|
||||
var cap0 int
|
||||
for i := 0; i < 5<<10; i++ {
|
||||
b.Write(buf)
|
||||
b.Read(buf)
|
||||
if i == 0 {
|
||||
cap0 = b.Cap()
|
||||
}
|
||||
}
|
||||
cap1 := b.Cap()
|
||||
// (*Buffer).grow allows for 2x capacity slop before sliding,
|
||||
// so set our error threshold at 3x.
|
||||
if cap1 > cap0*3 {
|
||||
t.Errorf("buffer cap = %d; too big (grew from %d)", cap1, cap0)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkWriteByte(b *testing.B) {
|
||||
const n = 4 << 10
|
||||
b.SetBytes(n)
|
||||
buf := NewBuffer(make([]byte, n))
|
||||
for i := 0; i < b.N; i++ {
|
||||
buf.Reset()
|
||||
for i := 0; i < n; i++ {
|
||||
buf.WriteByte('x')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// From Issue 5154.
|
||||
func BenchmarkBufferNotEmptyWriteRead(b *testing.B) {
|
||||
buf := make([]byte, 1024)
|
||||
for i := 0; i < b.N; i++ {
|
||||
var b Buffer
|
||||
b.Write(buf[0:1])
|
||||
for i := 0; i < 5<<10; i++ {
|
||||
b.Write(buf)
|
||||
b.Read(buf)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check that we don't compact too often. From Issue 5154.
|
||||
func BenchmarkBufferFullSmallReads(b *testing.B) {
|
||||
buf := make([]byte, 1024)
|
||||
for i := 0; i < b.N; i++ {
|
||||
var b Buffer
|
||||
b.Write(buf)
|
||||
for b.Len()+20 < b.Cap() {
|
||||
b.Write(buf[:10])
|
||||
}
|
||||
for i := 0; i < 5<<10; i++ {
|
||||
b.Read(buf[:1])
|
||||
b.Write(buf[:1])
|
||||
}
|
||||
}
|
||||
}
|
||||
3
go-buffer-pool/codecov.yml
Normal file
3
go-buffer-pool/codecov.yml
Normal file
@ -0,0 +1,3 @@
|
||||
coverage:
|
||||
range: "50...100"
|
||||
comment: off
|
||||
3
go-buffer-pool/go.mod
Normal file
3
go-buffer-pool/go.mod
Normal file
@ -0,0 +1,3 @@
|
||||
module github.com/libp2p/go-buffer-pool
|
||||
|
||||
go 1.22
|
||||
103
go-buffer-pool/pool.go
Normal file
103
go-buffer-pool/pool.go
Normal file
@ -0,0 +1,103 @@
|
||||
// Package pool provides a sync.Pool equivalent that buckets incoming
|
||||
// requests to one of 32 sub-pools, one for each power of 2, 0-32.
|
||||
//
|
||||
// import (pool "github.com/libp2p/go-buffer-pool")
|
||||
// var p pool.BufferPool
|
||||
//
|
||||
// small := make([]byte, 1024)
|
||||
// large := make([]byte, 4194304)
|
||||
// p.Put(small)
|
||||
// p.Put(large)
|
||||
//
|
||||
// small2 := p.Get(1024)
|
||||
// large2 := p.Get(4194304)
|
||||
// fmt.Println("small2 len:", len(small2))
|
||||
// fmt.Println("large2 len:", len(large2))
|
||||
//
|
||||
// // Output:
|
||||
// // small2 len: 1024
|
||||
// // large2 len: 4194304
|
||||
package pool
|
||||
|
||||
import (
|
||||
"math"
|
||||
"math/bits"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// GlobalPool is a static Pool for reusing byteslices of various sizes.
|
||||
var GlobalPool = new(BufferPool)
|
||||
|
||||
// MaxLength is the maximum length of an element that can be added to the Pool.
|
||||
const MaxLength = math.MaxInt32
|
||||
|
||||
// BufferPool is a pool to handle cases of reusing elements of varying sizes. It
|
||||
// maintains 32 internal pools, for each power of 2 in 0-32.
|
||||
//
|
||||
// You should generally just call the package level Get and Put methods or use
|
||||
// the GlobalPool BufferPool instead of constructing your own.
|
||||
//
|
||||
// You MUST NOT copy Pool after using.
|
||||
type BufferPool struct {
|
||||
pools [32]sync.Pool // a list of singlePools
|
||||
}
|
||||
|
||||
// Get retrieves a buffer of the appropriate length from the buffer pool or
|
||||
// allocates a new one. Get may choose to ignore the pool and treat it as empty.
|
||||
// Callers should not assume any relation between values passed to Put and the
|
||||
// values returned by Get.
|
||||
//
|
||||
// If no suitable buffer exists in the pool, Get creates one.
|
||||
func (p *BufferPool) Get(length int) []byte {
|
||||
if length == 0 {
|
||||
return nil
|
||||
}
|
||||
// Calling this function with a negative length is invalid.
|
||||
// make will panic if length is negative, so we don't have to.
|
||||
if length > MaxLength || length < 0 {
|
||||
return make([]byte, length)
|
||||
}
|
||||
idx := nextLogBase2(uint32(length))
|
||||
if ptr := p.pools[idx].Get(); ptr != nil {
|
||||
buf := ptr.([]byte)
|
||||
buf = buf[:uint32(length)]
|
||||
return buf
|
||||
}
|
||||
return make([]byte, 1<<idx)[:uint32(length)]
|
||||
}
|
||||
|
||||
// Put adds x to the pool.
|
||||
func (p *BufferPool) Put(buf []byte) {
|
||||
capacity := cap(buf)
|
||||
if capacity == 0 || capacity > MaxLength {
|
||||
return // drop it
|
||||
}
|
||||
idx := prevLogBase2(uint32(capacity))
|
||||
// nolint: staticcheck
|
||||
p.pools[idx].Put(buf)
|
||||
}
|
||||
|
||||
// Get retrieves a buffer of the appropriate length from the global buffer pool
|
||||
// (or allocates a new one).
|
||||
func Get(length int) []byte {
|
||||
return GlobalPool.Get(length)
|
||||
}
|
||||
|
||||
// Put returns a buffer to the global buffer pool.
|
||||
func Put(slice []byte) {
|
||||
GlobalPool.Put(slice)
|
||||
}
|
||||
|
||||
// Log of base two, round up (for v > 0).
|
||||
func nextLogBase2(v uint32) uint32 {
|
||||
return uint32(bits.Len32(v - 1))
|
||||
}
|
||||
|
||||
// Log of base two, round down (for v > 0)
|
||||
func prevLogBase2(num uint32) uint32 {
|
||||
next := nextLogBase2(num)
|
||||
if num == (1 << uint32(next)) {
|
||||
return next
|
||||
}
|
||||
return next - 1
|
||||
}
|
||||
185
go-buffer-pool/pool_test.go
Normal file
185
go-buffer-pool/pool_test.go
Normal file
@ -0,0 +1,185 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Pool is no-op under race detector, so all these tests do not work.
|
||||
//go:build !race
|
||||
|
||||
package pool
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"runtime"
|
||||
"runtime/debug"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRange(t *testing.T) {
|
||||
min := nextLogBase2(1)
|
||||
max := nextLogBase2(uint32(MaxLength))
|
||||
if int(max) != len(GlobalPool.pools)-1 {
|
||||
t.Errorf("expected %d pools, found %d", max, len(GlobalPool.pools))
|
||||
}
|
||||
if min != 0 {
|
||||
t.Errorf("unused min pool")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPool(t *testing.T) {
|
||||
// disable GC so we can control when it happens.
|
||||
defer debug.SetGCPercent(debug.SetGCPercent(-1))
|
||||
var p BufferPool
|
||||
|
||||
a := make([]byte, 21)
|
||||
a[0] = 1
|
||||
b := make([]byte, 2050)
|
||||
b[0] = 2
|
||||
p.Put(a)
|
||||
p.Put(b)
|
||||
if g := p.Get(16); &g[0] != &a[0] {
|
||||
t.Fatalf("got [%d,...]; want [1,...]", g[0])
|
||||
}
|
||||
if g := p.Get(2048); &g[0] != &b[0] {
|
||||
t.Fatalf("got [%d,...]; want [2,...]", g[0])
|
||||
}
|
||||
if g := p.Get(16); cap(g) != 16 || !bytes.Equal(g[:16], make([]byte, 16)) {
|
||||
t.Fatalf("got existing slice; want new slice")
|
||||
}
|
||||
if g := p.Get(2048); cap(g) != 2048 || !bytes.Equal(g[:2048], make([]byte, 2048)) {
|
||||
t.Fatalf("got existing slice; want new slice")
|
||||
}
|
||||
if g := p.Get(1); cap(g) != 1 || !bytes.Equal(g[:1], make([]byte, 1)) {
|
||||
t.Fatalf("got existing slice; want new slice")
|
||||
}
|
||||
d := make([]byte, 1023)
|
||||
d[0] = 3
|
||||
p.Put(d)
|
||||
if g := p.Get(1024); cap(g) != 1024 || !bytes.Equal(g, make([]byte, 1024)) {
|
||||
t.Fatalf("got existing slice; want new slice")
|
||||
}
|
||||
if g := p.Get(512); cap(g) != 1023 || g[0] != 3 {
|
||||
t.Fatalf("got [%d,...]; want [3,...]", g[0])
|
||||
}
|
||||
p.Put(a)
|
||||
|
||||
debug.SetGCPercent(100) // to allow following GC to actually run
|
||||
runtime.GC()
|
||||
// For some reason, you need to run GC twice on go 1.16 if you want it to reliably work.
|
||||
runtime.GC()
|
||||
if g := p.Get(10); &g[0] == &a[0] {
|
||||
t.Fatalf("got a; want new slice after GC")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPoolStressByteSlicePool(t *testing.T) {
|
||||
var p BufferPool
|
||||
|
||||
const P = 10
|
||||
chs := 10
|
||||
maxSize := 1 << 16
|
||||
N := int(1e4)
|
||||
if testing.Short() {
|
||||
N /= 100
|
||||
}
|
||||
done := make(chan bool)
|
||||
errs := make(chan error)
|
||||
for i := 0; i < P; i++ {
|
||||
go func() {
|
||||
ch := make(chan []byte, chs+1)
|
||||
|
||||
for i := 0; i < chs; i++ {
|
||||
j := rand.Int() % maxSize
|
||||
ch <- p.Get(j)
|
||||
}
|
||||
|
||||
for j := 0; j < N; j++ {
|
||||
r := 0
|
||||
for i := 0; i < chs; i++ {
|
||||
v := <-ch
|
||||
p.Put(v)
|
||||
r = rand.Int() % maxSize
|
||||
v = p.Get(r)
|
||||
if len(v) < r {
|
||||
errs <- fmt.Errorf("expect len(v) >= %d, got %d", j, len(v))
|
||||
}
|
||||
ch <- v
|
||||
}
|
||||
|
||||
if r%1000 == 0 {
|
||||
runtime.GC()
|
||||
}
|
||||
}
|
||||
done <- true
|
||||
}()
|
||||
}
|
||||
|
||||
for i := 0; i < P; {
|
||||
select {
|
||||
case <-done:
|
||||
i++
|
||||
case err := <-errs:
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkPool(b *testing.B) {
|
||||
var p BufferPool
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
i := 7
|
||||
for pb.Next() {
|
||||
if i > 1<<20 {
|
||||
i = 7
|
||||
} else {
|
||||
i = i << 1
|
||||
}
|
||||
b := p.Get(i)
|
||||
b[0] = byte(i)
|
||||
p.Put(b)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkAlloc(b *testing.B) {
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
i := 7
|
||||
for pb.Next() {
|
||||
if i > 1<<20 {
|
||||
i = 7
|
||||
} else {
|
||||
i = i << 1
|
||||
}
|
||||
b := make([]byte, i)
|
||||
b[1] = byte(i)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkPoolOverlflow(b *testing.B) {
|
||||
var p BufferPool
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
bufs := make([][]byte, 2100)
|
||||
for pow := uint32(0); pow < 21; pow++ {
|
||||
for i := 0; i < 100; i++ {
|
||||
bufs = append(bufs, p.Get(1<<pow))
|
||||
}
|
||||
}
|
||||
for _, b := range bufs {
|
||||
p.Put(b)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func ExampleGet() {
|
||||
buf := Get(100)
|
||||
fmt.Println("length", len(buf))
|
||||
fmt.Println("capacity", cap(buf))
|
||||
Put(buf)
|
||||
// Output:
|
||||
// length 100
|
||||
// capacity 128
|
||||
}
|
||||
3
go-buffer-pool/version.json
Normal file
3
go-buffer-pool/version.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"version": "v0.1.0"
|
||||
}
|
||||
119
go-buffer-pool/writer.go
Normal file
119
go-buffer-pool/writer.go
Normal file
@ -0,0 +1,119 @@
|
||||
package pool
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"io"
|
||||
"sync"
|
||||
)
|
||||
|
||||
const WriterBufferSize = 4096
|
||||
|
||||
var bufioWriterPool = sync.Pool{
|
||||
New: func() interface{} {
|
||||
return bufio.NewWriterSize(nil, WriterBufferSize)
|
||||
},
|
||||
}
|
||||
|
||||
// Writer is a buffered writer that returns its internal buffer in a pool when
|
||||
// not in use.
|
||||
type Writer struct {
|
||||
W io.Writer
|
||||
bufw *bufio.Writer
|
||||
}
|
||||
|
||||
func (w *Writer) ensureBuffer() {
|
||||
if w.bufw == nil {
|
||||
w.bufw = bufioWriterPool.Get().(*bufio.Writer)
|
||||
w.bufw.Reset(w.W)
|
||||
}
|
||||
}
|
||||
|
||||
// Write writes the given byte slice to the underlying connection.
|
||||
//
|
||||
// Note: Write won't return the write buffer to the pool even if it ends up
|
||||
// being empty after the write. You must call Flush() to do that.
|
||||
func (w *Writer) Write(b []byte) (int, error) {
|
||||
if w.bufw == nil {
|
||||
if len(b) >= WriterBufferSize {
|
||||
return w.W.Write(b)
|
||||
}
|
||||
w.bufw = bufioWriterPool.Get().(*bufio.Writer)
|
||||
w.bufw.Reset(w.W)
|
||||
}
|
||||
return w.bufw.Write(b)
|
||||
}
|
||||
|
||||
// Size returns the size of the underlying buffer.
|
||||
func (w *Writer) Size() int {
|
||||
return WriterBufferSize
|
||||
}
|
||||
|
||||
// Available returns the amount buffer space available.
|
||||
func (w *Writer) Available() int {
|
||||
if w.bufw != nil {
|
||||
return w.bufw.Available()
|
||||
}
|
||||
return WriterBufferSize
|
||||
}
|
||||
|
||||
// Buffered returns the amount of data buffered.
|
||||
func (w *Writer) Buffered() int {
|
||||
if w.bufw != nil {
|
||||
return w.bufw.Buffered()
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// WriteByte writes a single byte.
|
||||
func (w *Writer) WriteByte(b byte) error {
|
||||
w.ensureBuffer()
|
||||
return w.bufw.WriteByte(b)
|
||||
}
|
||||
|
||||
// WriteRune writes a single rune, returning the number of bytes written.
|
||||
func (w *Writer) WriteRune(r rune) (int, error) {
|
||||
w.ensureBuffer()
|
||||
return w.bufw.WriteRune(r)
|
||||
}
|
||||
|
||||
// WriteString writes a string, returning the number of bytes written.
|
||||
func (w *Writer) WriteString(s string) (int, error) {
|
||||
w.ensureBuffer()
|
||||
return w.bufw.WriteString(s)
|
||||
}
|
||||
|
||||
// Flush flushes the write buffer, if any, and returns it to the pool.
|
||||
func (w *Writer) Flush() error {
|
||||
if w.bufw == nil {
|
||||
return nil
|
||||
}
|
||||
if err := w.bufw.Flush(); err != nil {
|
||||
return err
|
||||
}
|
||||
w.bufw.Reset(nil)
|
||||
bufioWriterPool.Put(w.bufw)
|
||||
w.bufw = nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// Close flushes the underlying writer and closes it if it implements the
|
||||
// io.Closer interface.
|
||||
//
|
||||
// Note: Close() closes the writer even if Flush() fails to avoid leaking system
|
||||
// resources. If you want to make sure Flush() succeeds, call it first.
|
||||
func (w *Writer) Close() error {
|
||||
var (
|
||||
ferr, cerr error
|
||||
)
|
||||
ferr = w.Flush()
|
||||
|
||||
// always close even if flush fails.
|
||||
if closer, ok := w.W.(io.Closer); ok {
|
||||
cerr = closer.Close()
|
||||
}
|
||||
|
||||
if ferr != nil {
|
||||
return ferr
|
||||
}
|
||||
return cerr
|
||||
}
|
||||
91
go-buffer-pool/writer_test.go
Normal file
91
go-buffer-pool/writer_test.go
Normal file
@ -0,0 +1,91 @@
|
||||
package pool
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func checkSize(t *testing.T, w *Writer) {
|
||||
if w.Size()-w.Buffered() != w.Available() {
|
||||
t.Fatalf("size (%d), buffered (%d), available (%d) mismatch", w.Size(), w.Buffered(), w.Available())
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriter(t *testing.T) {
|
||||
var b bytes.Buffer
|
||||
w := Writer{W: &b}
|
||||
n, err := w.Write([]byte("foobar"))
|
||||
checkSize(t, &w)
|
||||
|
||||
if err != nil || n != 6 {
|
||||
t.Fatalf("write failed: %d, %s", n, err)
|
||||
}
|
||||
if b.Len() != 0 {
|
||||
t.Fatal("expected the buffer to be empty")
|
||||
}
|
||||
if w.Buffered() != 6 {
|
||||
t.Fatalf("expected 6 bytes to be buffered, got %d", w.Buffered())
|
||||
}
|
||||
checkSize(t, &w)
|
||||
if err := w.Flush(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
checkSize(t, &w)
|
||||
if err := w.Flush(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
checkSize(t, &w)
|
||||
if b.String() != "foobar" {
|
||||
t.Fatal("expected to have written foobar")
|
||||
}
|
||||
b.Reset()
|
||||
|
||||
buf := make([]byte, WriterBufferSize)
|
||||
n, err = w.Write(buf)
|
||||
if n != WriterBufferSize || err != nil {
|
||||
t.Fatalf("write failed: %d, %s", n, err)
|
||||
}
|
||||
checkSize(t, &w)
|
||||
if b.Len() != WriterBufferSize {
|
||||
t.Fatal("large write should have gone through directly")
|
||||
}
|
||||
if err := w.Flush(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
checkSize(t, &w)
|
||||
|
||||
b.Reset()
|
||||
if err := w.WriteByte(1); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if w.Buffered() != 1 {
|
||||
t.Fatalf("expected 1 byte to be buffered, got %d", w.Buffered())
|
||||
}
|
||||
if n, err := w.WriteRune('1'); err != nil || n != 1 {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if w.Buffered() != 2 {
|
||||
t.Fatalf("expected 2 bytes to be buffered, got %d", w.Buffered())
|
||||
}
|
||||
checkSize(t, &w)
|
||||
if n, err := w.WriteString("foobar"); err != nil || n != 6 {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if w.Buffered() != 8 {
|
||||
t.Fatalf("expected 8 bytes to be buffered, got %d", w.Buffered())
|
||||
}
|
||||
checkSize(t, &w)
|
||||
if b.Len() != 0 {
|
||||
t.Fatal("write should have been buffered")
|
||||
}
|
||||
n, err = w.Write(buf)
|
||||
if n != WriterBufferSize || err != nil {
|
||||
t.Fatalf("write failed: %d, %s", n, err)
|
||||
}
|
||||
if b.Len() != WriterBufferSize || b.Bytes()[0] != 1 || b.String()[1:8] != "1foobar" {
|
||||
t.Fatalf("failed to flush properly: len:%d, prefix:%#v", b.Len(), b.Bytes()[:10])
|
||||
}
|
||||
if err := w.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
@ -40,6 +40,7 @@ var (
|
||||
BlossomSubHistoryLength = 5
|
||||
BlossomSubHistoryGossip = 3
|
||||
BlossomSubDlazy = 6
|
||||
BlossomSubGossipFactor = 0.25
|
||||
BlossomSubGossipRetransmission = 3
|
||||
BlossomSubBitmaskWidth = 256
|
||||
BlossomSubHeartbeatInitialDelay = 100 * time.Millisecond
|
||||
@ -116,9 +117,15 @@ type BlossomSubParams struct {
|
||||
|
||||
// Dlazy affects how many peers we will emit gossip to at each heartbeat.
|
||||
// We will send gossip to at least Dlazy peers outside our mesh. The actual
|
||||
// number may be less, depending on how many peers we're connected to.
|
||||
// number may be more, depending on GossipFactor and how many peers we're
|
||||
// connected to.
|
||||
Dlazy int
|
||||
|
||||
// GossipFactor affects how many peers we will emit gossip to at each heartbeat.
|
||||
// We will send gossip to GossipFactor * (total number of non-mesh peers), or
|
||||
// Dlazy, whichever is greater.
|
||||
GossipFactor float64
|
||||
|
||||
// GossipRetransmission controls how many times we will allow a peer to request
|
||||
// the same message id through IWANT gossip before we start ignoring them. This is designed
|
||||
// to prevent peers from spamming us with requests and wasting our resources.
|
||||
@ -313,6 +320,7 @@ func DefaultBlossomSubParams() BlossomSubParams {
|
||||
HistoryLength: BlossomSubHistoryLength,
|
||||
HistoryGossip: BlossomSubHistoryGossip,
|
||||
Dlazy: BlossomSubDlazy,
|
||||
GossipFactor: BlossomSubGossipFactor,
|
||||
GossipRetransmission: BlossomSubGossipRetransmission,
|
||||
HeartbeatInitialDelay: BlossomSubHeartbeatInitialDelay,
|
||||
HeartbeatInterval: BlossomSubHeartbeatInterval,
|
||||
@ -693,62 +701,31 @@ func (bs *BlossomSubRouter) RemovePeer(p peer.ID) {
|
||||
}
|
||||
|
||||
func (bs *BlossomSubRouter) EnoughPeers(bitmask []byte, suggested int) bool {
|
||||
sliced := SliceBitmask(bitmask)
|
||||
// bloom:
|
||||
if len(sliced) != 1 {
|
||||
// check all peers in the bitmask
|
||||
peers := bs.p.getPeersInBitmask(bitmask)
|
||||
if len(peers) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
fsPeers, bsPeers := 0, 0
|
||||
|
||||
for _, p := range peers {
|
||||
if !bs.feature(BlossomSubFeatureMesh, bs.peers[p]) {
|
||||
fsPeers++
|
||||
}
|
||||
}
|
||||
|
||||
// BlossomSub peers
|
||||
bsPeers = len(peers)
|
||||
|
||||
if suggested == 0 {
|
||||
suggested = bs.params.Dlo
|
||||
}
|
||||
|
||||
if fsPeers+bsPeers >= suggested || bsPeers >= bs.params.Dhi {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
} else { // classic gossip
|
||||
tmap, ok := bs.p.bitmasks[string(bitmask)]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
fsPeers, bsPeers := 0, 0
|
||||
// floodsub peers
|
||||
for p := range tmap {
|
||||
if !bs.feature(BlossomSubFeatureMesh, bs.peers[p]) {
|
||||
fsPeers++
|
||||
}
|
||||
}
|
||||
|
||||
// BlossomSub peers
|
||||
bsPeers = len(bs.mesh[string(bitmask)])
|
||||
|
||||
if suggested == 0 {
|
||||
suggested = bs.params.Dlo
|
||||
}
|
||||
|
||||
if fsPeers+bsPeers >= suggested || bsPeers >= bs.params.Dhi {
|
||||
return true
|
||||
}
|
||||
|
||||
tmap, ok := bs.p.bitmasks[string(bitmask)]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
fsPeers, bsPeers := 0, 0
|
||||
// floodsub peers
|
||||
for p := range tmap {
|
||||
if !bs.feature(BlossomSubFeatureMesh, bs.peers[p]) {
|
||||
fsPeers++
|
||||
}
|
||||
}
|
||||
|
||||
// BlossomSub peers
|
||||
bsPeers = len(bs.mesh[string(bitmask)])
|
||||
|
||||
if suggested == 0 {
|
||||
suggested = bs.params.Dlo
|
||||
}
|
||||
|
||||
if fsPeers+bsPeers >= suggested || bsPeers >= bs.params.Dhi {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (bs *BlossomSubRouter) PeerScore(p peer.ID) float64 {
|
||||
@ -943,6 +920,13 @@ func (bs *BlossomSubRouter) handleIWant(p peer.ID, ctl *pb.ControlMessage) []*pb
|
||||
|
||||
msgs := make([]*pb.Message, 0, len(ihave))
|
||||
for _, msg := range ihave {
|
||||
if peer.ID(msg.GetFrom()) == p {
|
||||
continue
|
||||
}
|
||||
mid := bs.p.idGen.RawID(msg)
|
||||
if _, ok := bs.unwanted[p][string(mid)]; ok {
|
||||
continue
|
||||
}
|
||||
msgs = append(msgs, msg)
|
||||
}
|
||||
|
||||
@ -1052,31 +1036,15 @@ func (bs *BlossomSubRouter) handlePrune(p peer.ID, ctl *pb.ControlMessage) {
|
||||
|
||||
for _, prune := range ctl.GetPrune() {
|
||||
bitmask := prune.GetBitmask()
|
||||
sliced := SliceBitmask(bitmask)
|
||||
// bloom publish:
|
||||
if len(sliced) != 1 {
|
||||
// any peers in all slices of the bitmask?
|
||||
peers := bs.p.getPeersInBitmask(bitmask)
|
||||
if len(peers) == 0 {
|
||||
return
|
||||
}
|
||||
peers, ok := bs.mesh[string(bitmask)]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, p := range peers {
|
||||
log.Debugf("PRUNE: Remove mesh link to %s in %s", p, bitmask)
|
||||
bs.tracer.Prune(p, bitmask)
|
||||
delete(bs.p.bitmasks[string(bitmask)], p)
|
||||
}
|
||||
} else { // classic gossip mesh
|
||||
peers, ok := bs.mesh[string(bitmask)]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
if _, inMesh := peers[p]; inMesh {
|
||||
log.Debugf("PRUNE: Remove mesh link to %s in %s", p, bitmask)
|
||||
bs.tracer.Prune(p, bitmask)
|
||||
delete(peers, p)
|
||||
}
|
||||
if _, inMesh := peers[p]; inMesh {
|
||||
log.Debugf("PRUNE: Remove mesh link to %s in %s", p, bitmask)
|
||||
bs.tracer.Prune(p, bitmask)
|
||||
delete(peers, p)
|
||||
}
|
||||
|
||||
// is there a backoff specified by the peer? if so obey it.
|
||||
@ -1227,22 +1195,13 @@ func (bs *BlossomSubRouter) Publish(msg *Message) {
|
||||
|
||||
from := msg.ReceivedFrom
|
||||
bitmask := msg.GetBitmask()
|
||||
originalSender := peer.ID(msg.GetFrom())
|
||||
mid := string(bs.p.idGen.ID(msg))
|
||||
|
||||
tosend := make(map[peer.ID]struct{})
|
||||
var toSendAll []map[peer.ID]struct{}
|
||||
for _, bitmask := range SliceBitmask(bitmask) {
|
||||
tosend := make(map[peer.ID]struct{})
|
||||
|
||||
sliced := SliceBitmask(bitmask)
|
||||
// bloom publish:
|
||||
if len(sliced) != 1 {
|
||||
// any peers in all slices of the bitmask?
|
||||
peers := bs.p.getPeersInBitmask(bitmask)
|
||||
if len(peers) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
for _, p := range peers {
|
||||
tosend[p] = struct{}{}
|
||||
}
|
||||
} else { // classic gossip mesh
|
||||
// any peers in the bitmask?
|
||||
tmap, ok := bs.p.bitmasks[string(bitmask)]
|
||||
if !ok {
|
||||
@ -1296,21 +1255,27 @@ func (bs *BlossomSubRouter) Publish(msg *Message) {
|
||||
tosend[p] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
delete(tosend, from)
|
||||
delete(tosend, originalSender)
|
||||
for p := range tosend {
|
||||
if _, ok := bs.unwanted[p][mid]; ok {
|
||||
delete(tosend, p)
|
||||
}
|
||||
}
|
||||
|
||||
if len(tosend) > 0 {
|
||||
toSendAll = append(toSendAll, tosend)
|
||||
}
|
||||
}
|
||||
|
||||
if len(toSendAll) == 0 {
|
||||
return
|
||||
}
|
||||
toSend := toSendAll[rand.Intn(len(toSendAll))]
|
||||
|
||||
out := rpcWithMessages(msg.Message)
|
||||
for pid := range tosend {
|
||||
if pid == from || pid == peer.ID(msg.GetFrom()) {
|
||||
continue
|
||||
}
|
||||
|
||||
mid := bs.p.idGen.ID(msg)
|
||||
// Check if it has already received an IDONTWANT for the message.
|
||||
// If so, don't send it to the peer
|
||||
if _, ok := bs.unwanted[pid][string(mid)]; ok {
|
||||
continue
|
||||
}
|
||||
|
||||
for pid := range toSend {
|
||||
bs.sendRPC(pid, out, false)
|
||||
}
|
||||
}
|
||||
@ -1374,56 +1339,24 @@ func (bs *BlossomSubRouter) Join(bitmask []byte) {
|
||||
}
|
||||
|
||||
func (bs *BlossomSubRouter) Leave(bitmask []byte) {
|
||||
sliced := SliceBitmask(bitmask)
|
||||
// bloom publish:
|
||||
if len(sliced) != 1 {
|
||||
// any peers in all slices of the bitmask?
|
||||
peers := bs.p.getPeersInBitmask(bitmask)
|
||||
if len(peers) == 0 {
|
||||
return
|
||||
}
|
||||
gmap, ok := bs.mesh[string(bitmask)]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
for _, s := range sliced {
|
||||
_, ok := bs.mesh[string(s)]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
log.Debugf("LEAVE %s", bitmask)
|
||||
bs.tracer.Leave(bitmask)
|
||||
|
||||
log.Debugf("LEAVE %s", bitmask)
|
||||
bs.tracer.Leave(bitmask)
|
||||
delete(bs.mesh, string(bitmask))
|
||||
|
||||
delete(bs.mesh, string(bitmask))
|
||||
}
|
||||
|
||||
for _, p := range peers {
|
||||
log.Debugf("LEAVE: Remove mesh link to %s in %s", p, bitmask)
|
||||
bs.tracer.Prune(p, bitmask)
|
||||
bs.sendPrune(p, bitmask, true)
|
||||
// Add a backoff to this peer to prevent us from eagerly
|
||||
// re-grafting this peer into our mesh if we rejoin this
|
||||
// bitmask before the backoff period ends.
|
||||
bs.addBackoff(p, bitmask, true)
|
||||
}
|
||||
} else { // classic gossip mesh
|
||||
gmap, ok := bs.mesh[string(bitmask)]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
log.Debugf("LEAVE %s", bitmask)
|
||||
bs.tracer.Leave(bitmask)
|
||||
|
||||
delete(bs.mesh, string(bitmask))
|
||||
|
||||
for p := range gmap {
|
||||
log.Debugf("LEAVE: Remove mesh link to %s in %s", p, bitmask)
|
||||
bs.tracer.Prune(p, bitmask)
|
||||
bs.sendPrune(p, bitmask, true)
|
||||
// Add a backoff to this peer to prevent us from eagerly
|
||||
// re-grafting this peer into our mesh if we rejoin this
|
||||
// bitmask before the backoff period ends.
|
||||
bs.addBackoff(p, bitmask, true)
|
||||
}
|
||||
for p := range gmap {
|
||||
log.Debugf("LEAVE: Remove mesh link to %s in %s", p, bitmask)
|
||||
bs.tracer.Prune(p, bitmask)
|
||||
bs.sendPrune(p, bitmask, true)
|
||||
// Add a backoff to this peer to prevent us from eagerly
|
||||
// re-grafting this peer into our mesh if we rejoin this
|
||||
// bitmask before the backoff period ends.
|
||||
bs.addBackoff(p, bitmask, true)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1469,18 +1402,18 @@ func (bs *BlossomSubRouter) sendRPC(p peer.ID, out *RPC, fast bool) {
|
||||
}
|
||||
|
||||
// If we're below the max message size, go ahead and send
|
||||
if out.Size() < bs.p.maxMessageSize {
|
||||
if out.Size() < bs.p.softMaxMessageSize {
|
||||
bs.doSendRPC(out, p, mch, fast)
|
||||
return
|
||||
}
|
||||
|
||||
outCopy := copyRPC(out)
|
||||
// Potentially split the RPC into multiple RPCs that are below the max message size
|
||||
outRPCs := appendOrMergeRPC(nil, bs.p.maxMessageSize, outCopy)
|
||||
outRPCs := appendOrMergeRPC(nil, bs.p.softMaxMessageSize, outCopy)
|
||||
for _, rpc := range outRPCs {
|
||||
if rpc.Size() > bs.p.maxMessageSize {
|
||||
if rpc.Size() > bs.p.hardMaxMessageSize {
|
||||
// This should only happen if a single message/control is above the maxMessageSize.
|
||||
bs.doDropRPC(out, p, fmt.Sprintf("Dropping oversized RPC. Size: %d, limit: %d. (Over by %d bytes)", rpc.Size(), bs.p.maxMessageSize, rpc.Size()-bs.p.maxMessageSize))
|
||||
bs.doDropRPC(out, p, fmt.Sprintf("Dropping oversized RPC. Size: %d, limit: %d. (Over by %d bytes)", rpc.Size(), bs.p.hardMaxMessageSize, rpc.Size()-bs.p.hardMaxMessageSize))
|
||||
continue
|
||||
}
|
||||
bs.doSendRPC(rpc, p, mch, fast)
|
||||
@ -2070,6 +2003,8 @@ func (bs *BlossomSubRouter) emitGossip(bitmask []byte, exclude map[peer.ID]struc
|
||||
}
|
||||
|
||||
target := bs.params.Dlazy
|
||||
factor := int(bs.params.GossipFactor * float64(len(peers)))
|
||||
target = max(target, factor)
|
||||
|
||||
if target > len(peers) {
|
||||
target = len(peers)
|
||||
|
||||
@ -1700,9 +1700,10 @@ func TestBlossomSubEnoughPeers(t *testing.T) {
|
||||
}
|
||||
|
||||
// at this point we have no connections and no mesh, so EnoughPeers should return false
|
||||
// NOTE: EnoughPeers operates with bloom filters, so we need to check for individual filters.
|
||||
res := make(chan bool, 1)
|
||||
psubs[0].eval <- func() {
|
||||
res <- psubs[0].rt.EnoughPeers([]byte{0x00, 0x00, 0x81, 0x00}, 0)
|
||||
res <- psubs[0].rt.EnoughPeers([]byte{0x00, 0x00, 0x80, 0x00}, 0)
|
||||
}
|
||||
enough := <-res
|
||||
if enough {
|
||||
@ -1715,7 +1716,7 @@ func TestBlossomSubEnoughPeers(t *testing.T) {
|
||||
time.Sleep(5 * time.Second)
|
||||
|
||||
psubs[0].eval <- func() {
|
||||
res <- psubs[0].rt.EnoughPeers([]byte{0x00, 0x00, 0x81, 0x00}, 0)
|
||||
res <- psubs[0].rt.EnoughPeers([]byte{0x00, 0x00, 0x80, 0x00}, 0)
|
||||
}
|
||||
enough = <-res
|
||||
if !enough {
|
||||
@ -2199,11 +2200,12 @@ func TestBlossomSubLeaveBitmask(t *testing.T) {
|
||||
leaveTime := time.Now()
|
||||
done := make(chan struct{})
|
||||
|
||||
// NOTE: Leave operates with bloom filters, so we need to check for individual filters.
|
||||
psubs[0].rt.(*BlossomSubRouter).p.eval <- func() {
|
||||
defer close(done)
|
||||
psubs[0].rt.Leave([]byte{0x00, 0x00, 0x81, 0x00})
|
||||
psubs[0].rt.Leave([]byte{0x00, 0x00, 0x80, 0x00})
|
||||
time.Sleep(time.Second)
|
||||
peerMap := psubs[0].rt.(*BlossomSubRouter).backoff[string([]byte{0x00, 0x00, 0x81, 0x00})]
|
||||
peerMap := psubs[0].rt.(*BlossomSubRouter).backoff[string([]byte{0x00, 0x00, 0x80, 0x00})]
|
||||
if len(peerMap) != 1 {
|
||||
t.Fatalf("No peer is populated in the backoff map for peer 0")
|
||||
}
|
||||
@ -2225,7 +2227,7 @@ func TestBlossomSubLeaveBitmask(t *testing.T) {
|
||||
// for peer 0.
|
||||
psubs[1].rt.(*BlossomSubRouter).p.eval <- func() {
|
||||
defer close(done)
|
||||
peerMap2 := psubs[1].rt.(*BlossomSubRouter).backoff[string([]byte{0x00, 0x00, 0x81, 0x00})]
|
||||
peerMap2 := psubs[1].rt.(*BlossomSubRouter).backoff[string([]byte{0x00, 0x00, 0x80, 0x00})]
|
||||
if len(peerMap2) != 1 {
|
||||
t.Fatalf("No peer is populated in the backoff map for peer 1")
|
||||
}
|
||||
@ -2312,7 +2314,7 @@ func (sq *sybilSquatter) handleStream(s network.Stream) {
|
||||
|
||||
// send a subscription for test in the output stream to become candidate for GRAFT
|
||||
// and then just read and ignore the incoming RPCs
|
||||
r := msgio.NewVarintReaderSize(s, DefaultMaxMessageSize)
|
||||
r := msgio.NewVarintReaderSize(s, DefaultHardMaxMessageSize)
|
||||
w := msgio.NewVarintWriter(os)
|
||||
truth := true
|
||||
bitmask := []byte{0x00, 0x00, 0x81, 0x00}
|
||||
@ -2532,7 +2534,7 @@ func TestBlossomSubRPCFragmentation(t *testing.T) {
|
||||
// (nMessages * msgSize) / ps.maxMessageSize total RPCs containing the messages we sent IWANTs for.
|
||||
// The actual number will probably be larger, since there's some overhead for the RPC itself, and
|
||||
// we probably aren't packing each RPC to it's maximum size
|
||||
minExpectedRPCS := (nMessages * msgSize) / ps.maxMessageSize
|
||||
minExpectedRPCS := (nMessages * msgSize) / ps.softMaxMessageSize
|
||||
if iwe.rpcsWithMessages < minExpectedRPCS {
|
||||
t.Fatalf("expected to receive at least %d RPCs containing messages, got %d", minExpectedRPCS, iwe.rpcsWithMessages)
|
||||
}
|
||||
@ -2561,7 +2563,7 @@ func (iwe *iwantEverything) handleStream(s network.Stream) {
|
||||
gossipMsgIdsReceived := make(map[string]struct{})
|
||||
|
||||
// send a subscription for test in the output stream to become candidate for gossip
|
||||
r := msgio.NewVarintReaderSize(s, DefaultMaxMessageSize)
|
||||
r := msgio.NewVarintReaderSize(s, DefaultHardMaxMessageSize)
|
||||
w := msgio.NewVarintWriter(os)
|
||||
truth := true
|
||||
bitmasks := [][]byte{{0x00, 0x00, 0x80, 0x00}, {0x00, 0x00, 0x01, 0x00}}
|
||||
|
||||
@ -55,7 +55,7 @@ func (p *PubSub) handleNewStream(s network.Stream) {
|
||||
p.inboundStreams[peer] = s
|
||||
p.inboundStreamsMx.Unlock()
|
||||
|
||||
r := msgio.NewVarintReaderSize(s, p.maxMessageSize)
|
||||
r := msgio.NewVarintReaderSize(s, p.hardMaxMessageSize)
|
||||
for {
|
||||
msgbytes, err := r.ReadMsg()
|
||||
if err != nil {
|
||||
|
||||
@ -1,13 +1,15 @@
|
||||
module source.quilibrium.com/quilibrium/monorepo/go-libp2p-blossomsub
|
||||
|
||||
go 1.21
|
||||
go 1.22
|
||||
|
||||
toolchain go1.22.4
|
||||
toolchain go1.22.5
|
||||
|
||||
replace github.com/multiformats/go-multiaddr => ../go-multiaddr
|
||||
|
||||
replace github.com/multiformats/go-multiaddr-dns => ../go-multiaddr-dns
|
||||
|
||||
replace github.com/libp2p/go-buffer-pool => ../go-buffer-pool
|
||||
|
||||
replace github.com/libp2p/go-libp2p => ../go-libp2p
|
||||
|
||||
replace github.com/libp2p/go-libp2p-gostream => ../go-libp2p-gostream
|
||||
|
||||
@ -140,8 +140,6 @@ github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8=
|
||||
github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg=
|
||||
github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM=
|
||||
github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro=
|
||||
github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94=
|
||||
@ -167,7 +165,6 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
|
||||
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
|
||||
github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4=
|
||||
github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY=
|
||||
github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8=
|
||||
@ -193,8 +190,6 @@ github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYg
|
||||
github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM=
|
||||
github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0=
|
||||
github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4=
|
||||
github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A=
|
||||
github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk=
|
||||
github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E=
|
||||
github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo=
|
||||
github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc=
|
||||
@ -463,7 +458,6 @@ golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
|
||||
@ -26,8 +26,11 @@ import (
|
||||
logging "github.com/ipfs/go-log/v2"
|
||||
)
|
||||
|
||||
// DefaultMaximumMessageSize is 10 MB.
|
||||
const DefaultMaxMessageSize = 10 << 20
|
||||
// DefaultSoftMaxMessageSize is 10 MiB.
|
||||
const DefaultSoftMaxMessageSize = 10 << 20
|
||||
|
||||
// DefaultHardMaxMessageSize is 20 MB.
|
||||
const DefaultHardMaxMessageSize = 10 << 21
|
||||
|
||||
var (
|
||||
// TimeCacheDuration specifies how long a message ID will be remembered as seen.
|
||||
@ -68,9 +71,12 @@ type PubSub struct {
|
||||
|
||||
peerFilter PeerFilter
|
||||
|
||||
// maxMessageSize is the maximum message size; it applies globally to all
|
||||
// bitmasks.
|
||||
maxMessageSize int
|
||||
// softMaxMessageSize is the maximum size of a single message fragment that
|
||||
// we will attempt to send.
|
||||
softMaxMessageSize int
|
||||
// hardMaxMessageSize is the maximum size of a single message fragment that
|
||||
// we will accept.
|
||||
hardMaxMessageSize int
|
||||
|
||||
// size of the outbound message channel that we maintain for each peer
|
||||
peerOutboundQueueSize int
|
||||
@ -265,7 +271,8 @@ func NewPubSub(ctx context.Context, h host.Host, rt PubSubRouter, opts ...Option
|
||||
val: newValidation(),
|
||||
peerFilter: DefaultPeerFilter,
|
||||
disc: &discover{},
|
||||
maxMessageSize: DefaultMaxMessageSize,
|
||||
softMaxMessageSize: DefaultSoftMaxMessageSize,
|
||||
hardMaxMessageSize: DefaultHardMaxMessageSize,
|
||||
peerOutboundQueueSize: 32,
|
||||
signID: h.ID(),
|
||||
signKey: nil,
|
||||
@ -520,9 +527,10 @@ func WithRawTracer(tracer RawTracer) Option {
|
||||
// another type of locator, such that messages can be fetched on-demand, rather
|
||||
// than being pushed proactively. Under this design, you'd use the pubsub layer
|
||||
// as a signalling system, rather than a data delivery system.
|
||||
func WithMaxMessageSize(maxMessageSize int) Option {
|
||||
func WithMaxMessageSize(softMaxMessageSize, hardMaxMessageSize int) Option {
|
||||
return func(ps *PubSub) error {
|
||||
ps.maxMessageSize = maxMessageSize
|
||||
ps.softMaxMessageSize = softMaxMessageSize
|
||||
ps.hardMaxMessageSize = hardMaxMessageSize
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
@ -251,7 +251,7 @@ func TestPBTracer(t *testing.T) {
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
r := msgio.NewVarintReaderSize(f, DefaultMaxMessageSize)
|
||||
r := msgio.NewVarintReaderSize(f, DefaultHardMaxMessageSize)
|
||||
|
||||
for {
|
||||
evt.Reset()
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
module github.com/libp2p/go-libp2p-kad-dht
|
||||
|
||||
go 1.21
|
||||
go 1.22
|
||||
|
||||
toolchain go1.22.5
|
||||
|
||||
retract v0.24.3 // this includes a breaking change and should have been released as v0.25.0
|
||||
|
||||
@ -8,6 +10,8 @@ replace github.com/multiformats/go-multiaddr => ../go-multiaddr
|
||||
|
||||
replace github.com/multiformats/go-multiaddr-dns => ../go-multiaddr-dns
|
||||
|
||||
replace github.com/libp2p/go-buffer-pool => ../go-buffer-pool
|
||||
|
||||
replace github.com/libp2p/go-libp2p => ../go-libp2p
|
||||
|
||||
require (
|
||||
|
||||
@ -246,10 +246,6 @@ github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ=
|
||||
github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM=
|
||||
github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8=
|
||||
github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg=
|
||||
github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c=
|
||||
github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic=
|
||||
github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8=
|
||||
|
||||
@ -1,9 +1,13 @@
|
||||
module github.com/libp2p/go-libp2p
|
||||
|
||||
go 1.21
|
||||
go 1.22
|
||||
|
||||
toolchain go1.22.5
|
||||
|
||||
retract v0.26.1 // Tag was applied incorrectly due to a bug in the release workflow.
|
||||
|
||||
replace github.com/libp2p/go-buffer-pool => ../go-buffer-pool
|
||||
|
||||
replace github.com/multiformats/go-multiaddr => ../go-multiaddr
|
||||
|
||||
replace github.com/multiformats/go-multiaddr-dns => ../go-multiaddr-dns
|
||||
|
||||
@ -186,8 +186,6 @@ github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8=
|
||||
github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg=
|
||||
github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM=
|
||||
github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro=
|
||||
github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94=
|
||||
|
||||
@ -13,6 +13,7 @@ type P2PConfig struct {
|
||||
HistoryLength int `yaml:"historyLength"`
|
||||
HistoryGossip int `yaml:"historyGossip"`
|
||||
DLazy int `yaml:"dLazy"`
|
||||
GossipFactor float64 `yaml:"gossipFactor"`
|
||||
GossipRetransmission int `yaml:"gossipRetransmission"`
|
||||
HeartbeatInitialDelay time.Duration `yaml:"heartbeatInitialDelay"`
|
||||
HeartbeatInterval time.Duration `yaml:"heartbeatInterval"`
|
||||
|
||||
@ -6,7 +6,14 @@ import (
|
||||
)
|
||||
|
||||
func GetMinimumVersionCutoff() time.Time {
|
||||
return time.Date(2024, time.November, 2, 0, 0, 0, 0, time.UTC)
|
||||
return time.Date(2024, time.November, 24, 0, 0, 0, 0, time.UTC)
|
||||
}
|
||||
|
||||
// Gets the minimum patch version – This should only be set in a release series
|
||||
// if there is something in the patch update that is needed to cut off unupgraded
|
||||
// peers. Be sure to update this to 0x00 for any new minor release
|
||||
func GetMinimumPatchVersion() byte {
|
||||
return 0x02
|
||||
}
|
||||
|
||||
func GetMinimumVersion() []byte {
|
||||
@ -36,9 +43,9 @@ func FormatVersion(version []byte) string {
|
||||
}
|
||||
|
||||
func GetPatchNumber() byte {
|
||||
return 0x01
|
||||
return 0x02
|
||||
}
|
||||
|
||||
func GetRCNumber() byte {
|
||||
return 0x01
|
||||
return 0x02
|
||||
}
|
||||
|
||||
@ -65,22 +65,24 @@ func (e *DataClockConsensusEngine) publishProof(
|
||||
|
||||
e.peerMapMx.Lock()
|
||||
e.peerMap[string(e.pubSub.GetPeerID())] = &peerInfo{
|
||||
peerId: e.pubSub.GetPeerID(),
|
||||
multiaddr: "",
|
||||
maxFrame: frame.FrameNumber,
|
||||
version: config.GetVersion(),
|
||||
timestamp: timestamp,
|
||||
peerId: e.pubSub.GetPeerID(),
|
||||
multiaddr: "",
|
||||
maxFrame: frame.FrameNumber,
|
||||
version: config.GetVersion(),
|
||||
patchVersion: config.GetPatchNumber(),
|
||||
timestamp: timestamp,
|
||||
totalDistance: e.dataTimeReel.GetTotalDistance().FillBytes(
|
||||
make([]byte, 256),
|
||||
),
|
||||
}
|
||||
list := &protobufs.DataPeerListAnnounce{
|
||||
Peer: &protobufs.DataPeer{
|
||||
PeerId: nil,
|
||||
Multiaddr: "",
|
||||
MaxFrame: frame.FrameNumber,
|
||||
Version: config.GetVersion(),
|
||||
Timestamp: timestamp,
|
||||
PeerId: nil,
|
||||
Multiaddr: "",
|
||||
MaxFrame: frame.FrameNumber,
|
||||
Version: config.GetVersion(),
|
||||
PatchVersion: []byte{config.GetPatchNumber()},
|
||||
Timestamp: timestamp,
|
||||
TotalDistance: e.dataTimeReel.GetTotalDistance().FillBytes(
|
||||
make([]byte, 256),
|
||||
),
|
||||
@ -100,19 +102,19 @@ func (e *DataClockConsensusEngine) insertTxMessage(
|
||||
filter []byte,
|
||||
message proto.Message,
|
||||
) error {
|
||||
any := &anypb.Any{}
|
||||
if err := any.MarshalFrom(message); err != nil {
|
||||
a := &anypb.Any{}
|
||||
if err := a.MarshalFrom(message); err != nil {
|
||||
return errors.Wrap(err, "publish message")
|
||||
}
|
||||
|
||||
any.TypeUrl = strings.Replace(
|
||||
any.TypeUrl,
|
||||
a.TypeUrl = strings.Replace(
|
||||
a.TypeUrl,
|
||||
"type.googleapis.com",
|
||||
"types.quilibrium.com",
|
||||
1,
|
||||
)
|
||||
|
||||
payload, err := proto.Marshal(any)
|
||||
payload, err := proto.Marshal(a)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "publish message")
|
||||
}
|
||||
@ -154,19 +156,19 @@ func (e *DataClockConsensusEngine) publishMessage(
|
||||
filter []byte,
|
||||
message proto.Message,
|
||||
) error {
|
||||
any := &anypb.Any{}
|
||||
if err := any.MarshalFrom(message); err != nil {
|
||||
a := &anypb.Any{}
|
||||
if err := a.MarshalFrom(message); err != nil {
|
||||
return errors.Wrap(err, "publish message")
|
||||
}
|
||||
|
||||
any.TypeUrl = strings.Replace(
|
||||
any.TypeUrl,
|
||||
a.TypeUrl = strings.Replace(
|
||||
a.TypeUrl,
|
||||
"type.googleapis.com",
|
||||
"types.quilibrium.com",
|
||||
1,
|
||||
)
|
||||
|
||||
payload, err := proto.Marshal(any)
|
||||
payload, err := proto.Marshal(a)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "publish message")
|
||||
}
|
||||
|
||||
@ -21,12 +21,13 @@ import (
|
||||
|
||||
const defaultSyncTimeout = 4 * time.Second
|
||||
|
||||
func (e *DataClockConsensusEngine) collect(
|
||||
enqueuedFrame *protobufs.ClockFrame,
|
||||
) (*protobufs.ClockFrame, error) {
|
||||
func (e *DataClockConsensusEngine) syncWithMesh() error {
|
||||
e.logger.Info("collecting vdf proofs")
|
||||
|
||||
latest := enqueuedFrame
|
||||
latest, err := e.dataTimeReel.Head()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "sync")
|
||||
}
|
||||
for {
|
||||
candidates := e.GetAheadPeers(max(latest.FrameNumber, e.latestFrameReceived))
|
||||
if len(candidates) == 0 {
|
||||
@ -36,11 +37,16 @@ func (e *DataClockConsensusEngine) collect(
|
||||
if candidate.MaxFrame <= max(latest.FrameNumber, e.latestFrameReceived) {
|
||||
continue
|
||||
}
|
||||
var err error
|
||||
latest, err = e.sync(latest, candidate.MaxFrame, candidate.PeerID)
|
||||
head, err := e.dataTimeReel.Head()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "sync")
|
||||
}
|
||||
if latest.FrameNumber < head.FrameNumber {
|
||||
latest = head
|
||||
}
|
||||
latest, err = e.syncWithPeer(latest, candidate.MaxFrame, candidate.PeerID)
|
||||
if err != nil {
|
||||
e.logger.Debug("error syncing frame", zap.Error(err))
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -51,7 +57,7 @@ func (e *DataClockConsensusEngine) collect(
|
||||
zap.Duration("frame_age", frametime.Since(latest)),
|
||||
)
|
||||
|
||||
return latest, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *DataClockConsensusEngine) prove(
|
||||
@ -268,7 +274,7 @@ func (e *DataClockConsensusEngine) GetAheadPeers(frameNumber uint64) []internal.
|
||||
return internal.WeightedSampleWithoutReplacement(candidates, len(candidates))
|
||||
}
|
||||
|
||||
func (e *DataClockConsensusEngine) sync(
|
||||
func (e *DataClockConsensusEngine) syncWithPeer(
|
||||
currentLatest *protobufs.ClockFrame,
|
||||
maxFrame uint64,
|
||||
peerId []byte,
|
||||
|
||||
@ -3,7 +3,8 @@ package data
|
||||
import (
|
||||
"context"
|
||||
"crypto"
|
||||
"encoding/binary"
|
||||
stderrors "errors"
|
||||
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"sync"
|
||||
@ -55,6 +56,7 @@ type peerInfo struct {
|
||||
timestamp int64
|
||||
lastSeen int64
|
||||
version []byte
|
||||
patchVersion byte
|
||||
totalDistance []byte
|
||||
}
|
||||
|
||||
@ -65,6 +67,7 @@ type DataClockConsensusEngine struct {
|
||||
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
wg sync.WaitGroup
|
||||
|
||||
lastProven uint64
|
||||
difficulty uint32
|
||||
@ -118,6 +121,8 @@ type DataClockConsensusEngine struct {
|
||||
stagedTransactions *protobufs.TokenRequests
|
||||
stagedTransactionsSet map[string]struct{}
|
||||
stagedTransactionsMx sync.Mutex
|
||||
validationFilter map[string]struct{}
|
||||
validationFilterMx sync.Mutex
|
||||
peerMapMx sync.RWMutex
|
||||
peerAnnounceMapMx sync.Mutex
|
||||
lastKeyBundleAnnouncementFrame uint64
|
||||
@ -132,7 +137,7 @@ type DataClockConsensusEngine struct {
|
||||
previousFrameProven *protobufs.ClockFrame
|
||||
previousTree *mt.MerkleTree
|
||||
clientReconnectTest int
|
||||
requestSyncCh chan *protobufs.ClockFrame
|
||||
requestSyncCh chan struct{}
|
||||
}
|
||||
|
||||
var _ consensus.DataConsensusEngine = (*DataClockConsensusEngine)(nil)
|
||||
@ -266,7 +271,8 @@ func NewDataClockConsensusEngine(
|
||||
rateLimit,
|
||||
time.Minute,
|
||||
),
|
||||
requestSyncCh: make(chan *protobufs.ClockFrame, 1),
|
||||
requestSyncCh: make(chan struct{}, 1),
|
||||
validationFilter: map[string]struct{}{},
|
||||
}
|
||||
|
||||
logger.Info("constructing consensus engine")
|
||||
@ -311,6 +317,7 @@ func (e *DataClockConsensusEngine) Start() <-chan error {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
e.wg.Add(3)
|
||||
go e.runFrameMessageHandler()
|
||||
go e.runTxMessageHandler()
|
||||
go e.runInfoMessageHandler()
|
||||
@ -359,7 +366,9 @@ func (e *DataClockConsensusEngine) Start() <-chan error {
|
||||
e.state = consensus.EngineStateCollecting
|
||||
e.stateMx.Unlock()
|
||||
|
||||
e.wg.Add(1)
|
||||
go func() {
|
||||
defer e.wg.Done()
|
||||
const baseDuration = 2 * time.Minute
|
||||
const maxBackoff = 3
|
||||
var currentBackoff = 0
|
||||
@ -395,7 +404,9 @@ func (e *DataClockConsensusEngine) Start() <-chan error {
|
||||
}
|
||||
}()
|
||||
|
||||
e.wg.Add(1)
|
||||
go func() {
|
||||
defer e.wg.Done()
|
||||
thresholdBeforeConfirming := 4
|
||||
frame, err := e.dataTimeReel.Head()
|
||||
if err != nil {
|
||||
@ -422,11 +433,12 @@ func (e *DataClockConsensusEngine) Start() <-chan error {
|
||||
timestamp := time.Now().UnixMilli()
|
||||
list := &protobufs.DataPeerListAnnounce{
|
||||
Peer: &protobufs.DataPeer{
|
||||
PeerId: nil,
|
||||
Multiaddr: "",
|
||||
MaxFrame: frame.FrameNumber,
|
||||
Version: config.GetVersion(),
|
||||
Timestamp: timestamp,
|
||||
PeerId: nil,
|
||||
Multiaddr: "",
|
||||
MaxFrame: frame.FrameNumber,
|
||||
Version: config.GetVersion(),
|
||||
PatchVersion: []byte{config.GetPatchNumber()},
|
||||
Timestamp: timestamp,
|
||||
TotalDistance: e.dataTimeReel.GetTotalDistance().FillBytes(
|
||||
make([]byte, 256),
|
||||
),
|
||||
@ -442,11 +454,12 @@ func (e *DataClockConsensusEngine) Start() <-chan error {
|
||||
|
||||
e.peerMapMx.Lock()
|
||||
e.peerMap[string(e.pubSub.GetPeerID())] = &peerInfo{
|
||||
peerId: e.pubSub.GetPeerID(),
|
||||
multiaddr: "",
|
||||
maxFrame: frame.FrameNumber,
|
||||
version: config.GetVersion(),
|
||||
timestamp: timestamp,
|
||||
peerId: e.pubSub.GetPeerID(),
|
||||
multiaddr: "",
|
||||
maxFrame: frame.FrameNumber,
|
||||
version: config.GetVersion(),
|
||||
patchVersion: config.GetPatchNumber(),
|
||||
timestamp: timestamp,
|
||||
totalDistance: e.dataTimeReel.GetTotalDistance().FillBytes(
|
||||
make([]byte, 256),
|
||||
),
|
||||
@ -500,11 +513,14 @@ func (e *DataClockConsensusEngine) Start() <-chan error {
|
||||
}
|
||||
}()
|
||||
|
||||
e.wg.Add(3)
|
||||
go e.runLoop()
|
||||
go e.runSync()
|
||||
go e.runFramePruning()
|
||||
|
||||
e.wg.Add(1)
|
||||
go func() {
|
||||
defer e.wg.Done()
|
||||
select {
|
||||
case <-e.ctx.Done():
|
||||
return
|
||||
@ -524,7 +540,9 @@ func (e *DataClockConsensusEngine) Start() <-chan error {
|
||||
|
||||
go e.runPreMidnightProofWorker()
|
||||
|
||||
e.wg.Add(1)
|
||||
go func() {
|
||||
defer e.wg.Done()
|
||||
if len(e.config.Engine.DataWorkerMultiaddrs) != 0 {
|
||||
e.clients, err = e.createParallelDataClientsFromList()
|
||||
if err != nil {
|
||||
@ -582,6 +600,7 @@ func (e *DataClockConsensusEngine) PerformTimeProof(
|
||||
i := i
|
||||
client := client
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
resp, err :=
|
||||
client.client.CalculateChallengeProof(
|
||||
e.ctx,
|
||||
@ -595,7 +614,6 @@ func (e *DataClockConsensusEngine) PerformTimeProof(
|
||||
)
|
||||
if err != nil {
|
||||
if status.Code(err) == codes.NotFound {
|
||||
wg.Done()
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -605,8 +623,6 @@ func (e *DataClockConsensusEngine) PerformTimeProof(
|
||||
} else {
|
||||
e.clients[client.index] = nil
|
||||
}
|
||||
|
||||
wg.Done()
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
@ -623,40 +639,32 @@ func (e *DataClockConsensusEngine) PerformTimeProof(
|
||||
func (e *DataClockConsensusEngine) Stop(force bool) <-chan error {
|
||||
e.logger.Info("stopping ceremony consensus engine")
|
||||
e.cancel()
|
||||
e.wg.Wait()
|
||||
e.stateMx.Lock()
|
||||
e.state = consensus.EngineStateStopping
|
||||
e.stateMx.Unlock()
|
||||
errChan := make(chan error)
|
||||
|
||||
msg := []byte("pause")
|
||||
msg = binary.BigEndian.AppendUint64(msg, e.GetFrame().FrameNumber)
|
||||
msg = append(msg, e.filter...)
|
||||
sig, err := e.pubSub.SignMessage(msg)
|
||||
if err != nil {
|
||||
pause := &protobufs.AnnounceProverPause{
|
||||
Filter: e.filter,
|
||||
FrameNumber: e.GetFrame().FrameNumber,
|
||||
}
|
||||
if err := pause.SignED448(e.pubSub.GetPublicKey(), e.pubSub.SignMessage); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := pause.Validate(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
e.publishMessage(e.txFilter, &protobufs.TokenRequest{
|
||||
Request: &protobufs.TokenRequest_Pause{
|
||||
Pause: &protobufs.AnnounceProverPause{
|
||||
Filter: e.filter,
|
||||
FrameNumber: e.GetFrame().FrameNumber,
|
||||
PublicKeySignatureEd448: &protobufs.Ed448Signature{
|
||||
PublicKey: &protobufs.Ed448PublicKey{
|
||||
KeyValue: e.pubSub.GetPublicKey(),
|
||||
},
|
||||
Signature: sig,
|
||||
},
|
||||
},
|
||||
},
|
||||
Timestamp: time.Now().UnixMilli(),
|
||||
})
|
||||
e.publishMessage(e.txFilter, pause.TokenRequest())
|
||||
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(len(e.executionEngines))
|
||||
executionErrors := make(chan error, len(e.executionEngines))
|
||||
for name := range e.executionEngines {
|
||||
name := name
|
||||
go func(name string) {
|
||||
defer wg.Done()
|
||||
frame, err := e.dataTimeReel.Head()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@ -664,9 +672,8 @@ func (e *DataClockConsensusEngine) Stop(force bool) <-chan error {
|
||||
|
||||
err = <-e.UnregisterExecutor(name, frame.FrameNumber, force)
|
||||
if err != nil {
|
||||
errChan <- err
|
||||
executionErrors <- err
|
||||
}
|
||||
wg.Done()
|
||||
}(name)
|
||||
}
|
||||
|
||||
@ -679,6 +686,7 @@ func (e *DataClockConsensusEngine) Stop(force bool) <-chan error {
|
||||
|
||||
e.logger.Info("waiting for execution engines to stop")
|
||||
wg.Wait()
|
||||
close(executionErrors)
|
||||
e.logger.Info("execution engines stopped")
|
||||
|
||||
e.dataTimeReel.Stop()
|
||||
@ -689,7 +697,12 @@ func (e *DataClockConsensusEngine) Stop(force bool) <-chan error {
|
||||
e.engineMx.Lock()
|
||||
defer e.engineMx.Unlock()
|
||||
go func() {
|
||||
errChan <- nil
|
||||
var errs []error
|
||||
for err := range executionErrors {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
err := stderrors.Join(errs...)
|
||||
errChan <- err
|
||||
}()
|
||||
return errChan
|
||||
}
|
||||
|
||||
@ -43,6 +43,7 @@ func (
|
||||
}
|
||||
|
||||
func (e *DataClockConsensusEngine) runFramePruning() {
|
||||
defer e.wg.Done()
|
||||
// A full prover should _never_ do this
|
||||
if e.GetFrameProverTries()[0].Contains(e.provingKeyAddress) ||
|
||||
e.config.Engine.MaxFrames == -1 || e.config.Engine.FullProver {
|
||||
@ -85,6 +86,7 @@ func (e *DataClockConsensusEngine) runFramePruning() {
|
||||
}
|
||||
|
||||
func (e *DataClockConsensusEngine) runSync() {
|
||||
defer e.wg.Done()
|
||||
// small optimization, beacon should never collect for now:
|
||||
if e.GetFrameProverTries()[0].Contains(e.provingKeyAddress) {
|
||||
return
|
||||
@ -94,25 +96,19 @@ func (e *DataClockConsensusEngine) runSync() {
|
||||
select {
|
||||
case <-e.ctx.Done():
|
||||
return
|
||||
case enqueuedFrame := <-e.requestSyncCh:
|
||||
if enqueuedFrame == nil {
|
||||
var err error
|
||||
enqueuedFrame, err = e.dataTimeReel.Head()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
case <-e.requestSyncCh:
|
||||
if err := e.pubSub.Bootstrap(e.ctx); err != nil {
|
||||
e.logger.Error("could not bootstrap", zap.Error(err))
|
||||
}
|
||||
if _, err := e.collect(enqueuedFrame); err != nil {
|
||||
e.logger.Error("could not collect", zap.Error(err))
|
||||
if err := e.syncWithMesh(); err != nil {
|
||||
e.logger.Error("could not sync", zap.Error(err))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (e *DataClockConsensusEngine) runLoop() {
|
||||
defer e.wg.Done()
|
||||
dataFrameCh := e.dataTimeReel.NewFrameCh()
|
||||
runOnce := true
|
||||
for {
|
||||
@ -149,6 +145,9 @@ func (e *DataClockConsensusEngine) runLoop() {
|
||||
case <-e.ctx.Done():
|
||||
return
|
||||
case dataFrame := <-dataFrameCh:
|
||||
e.validationFilterMx.Lock()
|
||||
e.validationFilter = make(map[string]struct{}, len(e.validationFilter))
|
||||
e.validationFilterMx.Unlock()
|
||||
if e.GetFrameProverTries()[0].Contains(e.provingKeyAddress) {
|
||||
if err = e.publishProof(dataFrame); err != nil {
|
||||
e.logger.Error("could not publish", zap.Error(err))
|
||||
@ -177,7 +176,7 @@ func (e *DataClockConsensusEngine) processFrame(
|
||||
var err error
|
||||
if !e.GetFrameProverTries()[0].Contains(e.provingKeyBytes) {
|
||||
select {
|
||||
case e.requestSyncCh <- dataFrame:
|
||||
case e.requestSyncCh <- struct{}{}:
|
||||
default:
|
||||
}
|
||||
}
|
||||
@ -298,7 +297,7 @@ func (e *DataClockConsensusEngine) processFrame(
|
||||
return latestFrame
|
||||
}
|
||||
modulo := len(outputs)
|
||||
proofTree, payload, output, err := tries.PackOutputIntoPayloadAndProof(
|
||||
proofTree, output, err := tries.PackOutputIntoPayloadAndProof(
|
||||
outputs,
|
||||
modulo,
|
||||
latestFrame,
|
||||
@ -314,11 +313,16 @@ func (e *DataClockConsensusEngine) processFrame(
|
||||
e.previousFrameProven = latestFrame
|
||||
e.previousTree = proofTree
|
||||
|
||||
sig, err := e.pubSub.SignMessage(
|
||||
payload,
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
mint := &protobufs.MintCoinRequest{
|
||||
Proofs: output,
|
||||
}
|
||||
if err := mint.SignED448(e.pubSub.GetPublicKey(), e.pubSub.SignMessage); err != nil {
|
||||
e.logger.Error("could not sign mint", zap.Error(err))
|
||||
return latestFrame
|
||||
}
|
||||
if err := mint.Validate(); err != nil {
|
||||
e.logger.Error("mint validation failed", zap.Error(err))
|
||||
return latestFrame
|
||||
}
|
||||
|
||||
e.logger.Info(
|
||||
@ -329,20 +333,7 @@ func (e *DataClockConsensusEngine) processFrame(
|
||||
zap.Duration("frame_age", frametime.Since(latestFrame)),
|
||||
)
|
||||
|
||||
e.publishMessage(e.txFilter, &protobufs.TokenRequest{
|
||||
Request: &protobufs.TokenRequest_Mint{
|
||||
Mint: &protobufs.MintCoinRequest{
|
||||
Proofs: output,
|
||||
Signature: &protobufs.Ed448Signature{
|
||||
PublicKey: &protobufs.Ed448PublicKey{
|
||||
KeyValue: e.pubSub.GetPublicKey(),
|
||||
},
|
||||
Signature: sig,
|
||||
},
|
||||
},
|
||||
},
|
||||
Timestamp: time.Now().UnixMilli(),
|
||||
})
|
||||
e.publishMessage(e.txFilter, mint.TokenRequest())
|
||||
|
||||
if e.config.Engine.AutoMergeCoins {
|
||||
_, addrs, _, err := e.coinStore.GetCoinsForOwner(
|
||||
@ -357,33 +348,29 @@ func (e *DataClockConsensusEngine) processFrame(
|
||||
}
|
||||
|
||||
if len(addrs) > 25 {
|
||||
message := []byte("merge")
|
||||
refs := []*protobufs.CoinRef{}
|
||||
for _, addr := range addrs {
|
||||
message = append(message, addr...)
|
||||
refs = append(refs, &protobufs.CoinRef{
|
||||
Address: addr,
|
||||
})
|
||||
}
|
||||
|
||||
sig, _ := e.pubSub.SignMessage(
|
||||
message,
|
||||
)
|
||||
merge := &protobufs.MergeCoinRequest{
|
||||
Coins: refs,
|
||||
}
|
||||
if err := merge.SignED448(
|
||||
e.pubSub.GetPublicKey(),
|
||||
e.pubSub.SignMessage,
|
||||
); err != nil {
|
||||
e.logger.Error("could not sign merge", zap.Error(err))
|
||||
return latestFrame
|
||||
}
|
||||
if err := merge.Validate(); err != nil {
|
||||
e.logger.Error("merge validation failed", zap.Error(err))
|
||||
return latestFrame
|
||||
}
|
||||
|
||||
e.publishMessage(e.txFilter, &protobufs.TokenRequest{
|
||||
Request: &protobufs.TokenRequest_Merge{
|
||||
Merge: &protobufs.MergeCoinRequest{
|
||||
Coins: refs,
|
||||
Signature: &protobufs.Ed448Signature{
|
||||
PublicKey: &protobufs.Ed448PublicKey{
|
||||
KeyValue: e.pubSub.GetPublicKey(),
|
||||
},
|
||||
Signature: sig,
|
||||
},
|
||||
},
|
||||
},
|
||||
Timestamp: time.Now().UnixMilli(),
|
||||
})
|
||||
e.publishMessage(e.txFilter, merge.TokenRequest())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ package data
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
@ -19,6 +20,7 @@ import (
|
||||
)
|
||||
|
||||
func (e *DataClockConsensusEngine) runFrameMessageHandler() {
|
||||
defer e.wg.Done()
|
||||
for {
|
||||
select {
|
||||
case <-e.ctx.Done():
|
||||
@ -32,31 +34,18 @@ func (e *DataClockConsensusEngine) runFrameMessageHandler() {
|
||||
continue
|
||||
}
|
||||
|
||||
any := &anypb.Any{}
|
||||
if err := proto.Unmarshal(msg.Payload, any); err != nil {
|
||||
a := &anypb.Any{}
|
||||
if err := proto.Unmarshal(msg.Payload, a); err != nil {
|
||||
e.logger.Error("error while unmarshaling", zap.Error(err))
|
||||
continue
|
||||
}
|
||||
|
||||
accepted := false
|
||||
switch any.TypeUrl {
|
||||
//expand for future message types
|
||||
case protobufs.ClockFrameType:
|
||||
accepted = true
|
||||
default:
|
||||
}
|
||||
|
||||
if !accepted {
|
||||
e.pubSub.AddPeerScore(message.From, -100000)
|
||||
continue
|
||||
}
|
||||
|
||||
switch any.TypeUrl {
|
||||
switch a.TypeUrl {
|
||||
case protobufs.ClockFrameType:
|
||||
if err := e.handleClockFrameData(
|
||||
message.From,
|
||||
msg.Address,
|
||||
any,
|
||||
a,
|
||||
false,
|
||||
); err != nil {
|
||||
e.logger.Debug("could not handle clock frame data", zap.Error(err))
|
||||
@ -67,6 +56,7 @@ func (e *DataClockConsensusEngine) runFrameMessageHandler() {
|
||||
}
|
||||
|
||||
func (e *DataClockConsensusEngine) runTxMessageHandler() {
|
||||
defer e.wg.Done()
|
||||
for {
|
||||
select {
|
||||
case <-e.ctx.Done():
|
||||
@ -80,21 +70,8 @@ func (e *DataClockConsensusEngine) runTxMessageHandler() {
|
||||
continue
|
||||
}
|
||||
|
||||
any := &anypb.Any{}
|
||||
if err := proto.Unmarshal(msg.Payload, any); err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
accepted := false
|
||||
switch any.TypeUrl {
|
||||
//expand for future message types
|
||||
case protobufs.TokenRequestType:
|
||||
accepted = true
|
||||
default:
|
||||
}
|
||||
|
||||
if !accepted {
|
||||
e.pubSub.AddPeerScore(message.From, -100000)
|
||||
a := &anypb.Any{}
|
||||
if err := proto.Unmarshal(msg.Payload, a); err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
@ -119,8 +96,8 @@ func (e *DataClockConsensusEngine) runTxMessageHandler() {
|
||||
}
|
||||
|
||||
for _, appMessage := range messages {
|
||||
appMsg := &anypb.Any{}
|
||||
err := proto.Unmarshal(appMessage.Payload, appMsg)
|
||||
a := &anypb.Any{}
|
||||
err := proto.Unmarshal(appMessage.Payload, a)
|
||||
if err != nil {
|
||||
e.logger.Error(
|
||||
"could not unmarshal app message",
|
||||
@ -130,10 +107,10 @@ func (e *DataClockConsensusEngine) runTxMessageHandler() {
|
||||
continue
|
||||
}
|
||||
|
||||
switch appMsg.TypeUrl {
|
||||
switch a.TypeUrl {
|
||||
case protobufs.TokenRequestType:
|
||||
t := &protobufs.TokenRequest{}
|
||||
err := proto.Unmarshal(appMsg.Value, t)
|
||||
err := proto.Unmarshal(a.Value, t)
|
||||
if err != nil {
|
||||
e.logger.Debug("could not unmarshal token request", zap.Error(err))
|
||||
continue
|
||||
@ -155,6 +132,7 @@ func (e *DataClockConsensusEngine) runTxMessageHandler() {
|
||||
}
|
||||
|
||||
func (e *DataClockConsensusEngine) runInfoMessageHandler() {
|
||||
defer e.wg.Done()
|
||||
for {
|
||||
select {
|
||||
case <-e.ctx.Done():
|
||||
@ -168,31 +146,18 @@ func (e *DataClockConsensusEngine) runInfoMessageHandler() {
|
||||
continue
|
||||
}
|
||||
|
||||
any := &anypb.Any{}
|
||||
if err := proto.Unmarshal(msg.Payload, any); err != nil {
|
||||
a := &anypb.Any{}
|
||||
if err := proto.Unmarshal(msg.Payload, a); err != nil {
|
||||
e.logger.Error("error while unmarshaling", zap.Error(err))
|
||||
continue
|
||||
}
|
||||
|
||||
accepted := false
|
||||
switch any.TypeUrl {
|
||||
//expand for future message types
|
||||
case protobufs.DataPeerListAnnounceType:
|
||||
accepted = true
|
||||
default:
|
||||
}
|
||||
|
||||
if !accepted {
|
||||
e.pubSub.AddPeerScore(message.From, -100000)
|
||||
continue
|
||||
}
|
||||
|
||||
switch any.TypeUrl {
|
||||
switch a.TypeUrl {
|
||||
case protobufs.DataPeerListAnnounceType:
|
||||
if err := e.handleDataPeerListAnnounce(
|
||||
message.From,
|
||||
msg.Address,
|
||||
any,
|
||||
a,
|
||||
); err != nil {
|
||||
e.logger.Debug("could not handle data peer list announce", zap.Error(err))
|
||||
}
|
||||
@ -305,6 +270,11 @@ func (e *DataClockConsensusEngine) handleDataPeerListAnnounce(
|
||||
return nil
|
||||
}
|
||||
|
||||
patchVersion := byte(0)
|
||||
if len(p.PatchVersion) == 1 {
|
||||
patchVersion = p.PatchVersion[0]
|
||||
}
|
||||
|
||||
if p.Version != nil &&
|
||||
bytes.Compare(p.Version, config.GetMinimumVersion()) < 0 &&
|
||||
p.Timestamp > config.GetMinimumVersionCutoff().UnixMilli() {
|
||||
@ -312,7 +282,7 @@ func (e *DataClockConsensusEngine) handleDataPeerListAnnounce(
|
||||
"peer provided outdated version, penalizing app score",
|
||||
zap.String("peer_id", peer.ID(peerID).String()),
|
||||
)
|
||||
e.pubSub.SetPeerScore(peerID, -1000000)
|
||||
e.pubSub.AddPeerScore(peerID, -1000)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -323,7 +293,7 @@ func (e *DataClockConsensusEngine) handleDataPeerListAnnounce(
|
||||
}
|
||||
e.peerMapMx.RUnlock()
|
||||
|
||||
e.pubSub.SetPeerScore(peerID, 10)
|
||||
e.pubSub.AddPeerScore(peerID, 10)
|
||||
|
||||
e.peerMapMx.RLock()
|
||||
existing, ok := e.peerMap[string(peerID)]
|
||||
@ -342,6 +312,7 @@ func (e *DataClockConsensusEngine) handleDataPeerListAnnounce(
|
||||
lastSeen: time.Now().Unix(),
|
||||
timestamp: p.Timestamp,
|
||||
version: p.Version,
|
||||
patchVersion: patchVersion,
|
||||
totalDistance: p.TotalDistance,
|
||||
}
|
||||
e.peerMapMx.Unlock()
|
||||
@ -349,7 +320,7 @@ func (e *DataClockConsensusEngine) handleDataPeerListAnnounce(
|
||||
select {
|
||||
case <-e.ctx.Done():
|
||||
return nil
|
||||
case e.requestSyncCh <- nil:
|
||||
case e.requestSyncCh <- struct{}{}:
|
||||
default:
|
||||
}
|
||||
|
||||
@ -370,10 +341,12 @@ func TokenRequestIdentifiers(transition *protobufs.TokenRequest) []string {
|
||||
return identifiers
|
||||
case *protobufs.TokenRequest_Mint:
|
||||
if len(t.Mint.Proofs) == 1 {
|
||||
return []string{fmt.Sprintf("mint-%x", sha3.Sum512(t.Mint.Proofs[0]))}
|
||||
return []string{fmt.Sprintf("mint-proof-%x", sha3.Sum512(t.Mint.Proofs[0]))}
|
||||
} else if len(t.Mint.Proofs) >= 3 {
|
||||
frameNumber := binary.BigEndian.Uint64(t.Mint.Proofs[2])
|
||||
return []string{fmt.Sprintf("mint-sign-%d-%x", frameNumber, t.Mint.Signature.PublicKey.KeyValue)}
|
||||
}
|
||||
// Large proofs are currently not deduplicated.
|
||||
return nil
|
||||
return []string{fmt.Sprintf("mint-sign-%x", t.Mint.Signature.PublicKey.KeyValue)}
|
||||
case *protobufs.TokenRequest_Announce:
|
||||
identifiers := make([]string, len(t.Announce.GetPublicKeySignaturesEd448()))
|
||||
for i, sig := range t.Announce.GetPublicKeySignaturesEd448() {
|
||||
|
||||
@ -2,6 +2,7 @@ package data
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
@ -51,6 +52,9 @@ func (e *DataClockConsensusEngine) validateTxMessage(peerID peer.ID, message *pb
|
||||
if err := proto.Unmarshal(a.Value, tx); err != nil {
|
||||
return p2p.ValidationResultReject
|
||||
}
|
||||
if err := tx.Validate(); err != nil {
|
||||
return p2p.ValidationResultReject
|
||||
}
|
||||
if mint := tx.GetMint(); mint != nil {
|
||||
if len(mint.Proofs) < 3 {
|
||||
return p2p.ValidationResultReject
|
||||
@ -61,18 +65,38 @@ func (e *DataClockConsensusEngine) validateTxMessage(peerID peer.ID, message *pb
|
||||
if len(mint.Proofs[2]) != 8 {
|
||||
return p2p.ValidationResultReject
|
||||
}
|
||||
|
||||
// cheap hack for handling protobuf trickery: because protobufs can be
|
||||
// serialized in infinite ways, message ids can be regenerated simply by
|
||||
// modifying the data without affecting the underlying signed message.
|
||||
// if this is encountered, go scorched earth on the sender – a thank you
|
||||
// message for destabilizing the network.
|
||||
frameNumber := binary.BigEndian.Uint64(mint.Proofs[2])
|
||||
id := fmt.Sprintf(
|
||||
"mint-sign-%d-%x",
|
||||
frameNumber,
|
||||
mint.Signature.PublicKey.KeyValue,
|
||||
)
|
||||
e.validationFilterMx.Lock()
|
||||
_, ok := e.validationFilter[id]
|
||||
e.validationFilter[id] = struct{}{}
|
||||
e.validationFilterMx.Unlock()
|
||||
if ok {
|
||||
e.pubSub.AddPeerScore(message.From, -1000000)
|
||||
return p2p.ValidationResultIgnore
|
||||
}
|
||||
|
||||
head, err := e.dataTimeReel.Head()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if frameNumber := binary.BigEndian.Uint64(mint.Proofs[2]); frameNumber+2 < head.FrameNumber {
|
||||
if frameNumber+2 < head.FrameNumber {
|
||||
return p2p.ValidationResultIgnore
|
||||
}
|
||||
}
|
||||
if tx.Timestamp == 0 {
|
||||
// NOTE: The timestamp was added in later versions of the protocol,
|
||||
// and as such it is possible to receive requests without it.
|
||||
// We avoid logging due to this reason.
|
||||
return p2p.ValidationResultAccept
|
||||
}
|
||||
if ts := time.UnixMilli(tx.Timestamp); time.Since(ts) > 10*time.Minute {
|
||||
|
||||
@ -186,6 +186,10 @@ func (e *DataClockConsensusEngine) handleMint(
|
||||
return nil, errors.Wrap(errors.New("wrong destination"), "handle mint")
|
||||
}
|
||||
|
||||
if err := t.Validate(); err != nil {
|
||||
return nil, errors.Wrap(application.ErrInvalidStateTransition, "handle mint")
|
||||
}
|
||||
|
||||
returnAddr := []byte{}
|
||||
e.preMidnightMintMx.Lock()
|
||||
if _, active := e.preMidnightMint[string(
|
||||
@ -211,17 +215,6 @@ func (e *DataClockConsensusEngine) handleMint(
|
||||
return nil, errors.Wrap(errors.New("busy"), "handle mint")
|
||||
}
|
||||
|
||||
if t == nil || t.Proofs == nil {
|
||||
return nil, errors.Wrap(application.ErrInvalidStateTransition, "handle mint")
|
||||
}
|
||||
|
||||
payload := []byte("mint")
|
||||
for _, p := range t.Proofs {
|
||||
payload = append(payload, p...)
|
||||
}
|
||||
if err := t.Signature.Verify(payload); err != nil {
|
||||
return nil, errors.Wrap(application.ErrInvalidStateTransition, "handle mint")
|
||||
}
|
||||
pk, err := pcrypto.UnmarshalEd448PublicKey(
|
||||
t.Signature.PublicKey.KeyValue,
|
||||
)
|
||||
|
||||
@ -36,6 +36,7 @@ type DataTimeReel struct {
|
||||
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
wg sync.WaitGroup
|
||||
|
||||
filter []byte
|
||||
engineConfig *config.EngineConfig
|
||||
@ -175,6 +176,7 @@ func (d *DataTimeReel) Start() error {
|
||||
d.headDistance, err = d.GetDistance(frame)
|
||||
}
|
||||
|
||||
d.wg.Add(1)
|
||||
go d.runLoop()
|
||||
|
||||
return nil
|
||||
@ -253,6 +255,7 @@ func (d *DataTimeReel) BadFrameCh() <-chan *protobufs.ClockFrame {
|
||||
|
||||
func (d *DataTimeReel) Stop() {
|
||||
d.cancel()
|
||||
d.wg.Wait()
|
||||
}
|
||||
|
||||
func (d *DataTimeReel) createGenesisFrame() (
|
||||
@ -338,6 +341,7 @@ func (d *DataTimeReel) createGenesisFrame() (
|
||||
|
||||
// Main data consensus loop
|
||||
func (d *DataTimeReel) runLoop() {
|
||||
defer d.wg.Done()
|
||||
for {
|
||||
select {
|
||||
case <-d.ctx.Done():
|
||||
|
||||
@ -161,15 +161,12 @@ func (a *TokenApplication) ApplyTransitions(
|
||||
i := i
|
||||
switch t := transition.Request.(type) {
|
||||
case *protobufs.TokenRequest_Mint:
|
||||
if t == nil || t.Mint.Proofs == nil || t.Mint.Signature == nil {
|
||||
if t == nil {
|
||||
fails[i] = transition
|
||||
continue
|
||||
}
|
||||
|
||||
payload := []byte("mint")
|
||||
for _, p := range t.Mint.Proofs {
|
||||
payload = append(payload, p...)
|
||||
}
|
||||
if err := t.Mint.Signature.Verify(payload); err != nil {
|
||||
if err := t.Mint.Validate(); err != nil {
|
||||
fails[i] = transition
|
||||
continue
|
||||
}
|
||||
|
||||
@ -177,6 +174,7 @@ func (a *TokenApplication) ApplyTransitions(
|
||||
t.Mint.Signature.PublicKey.KeyValue,
|
||||
)
|
||||
if err != nil {
|
||||
fails[i] = transition
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
@ -16,19 +16,16 @@ func (a *TokenApplication) handleMerge(
|
||||
lockMap map[string]struct{},
|
||||
t *protobufs.MergeCoinRequest,
|
||||
) ([]*protobufs.TokenOutput, error) {
|
||||
if err := t.Validate(); err != nil {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle merge")
|
||||
}
|
||||
|
||||
newCoin := &protobufs.Coin{}
|
||||
newTotal := new(big.Int)
|
||||
newIntersection := make([]byte, 1024)
|
||||
payload := []byte("merge")
|
||||
if t == nil || t.Coins == nil || t.Signature == nil {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle merge")
|
||||
}
|
||||
|
||||
addresses := [][]byte{}
|
||||
for _, c := range t.Coins {
|
||||
if c.Address == nil || len(c.Address) != 32 {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle merge")
|
||||
}
|
||||
|
||||
if _, touched := lockMap[string(c.Address)]; touched {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle merge")
|
||||
}
|
||||
@ -40,14 +37,6 @@ func (a *TokenApplication) handleMerge(
|
||||
}
|
||||
|
||||
addresses = append(addresses, c.Address)
|
||||
payload = append(payload, c.Address...)
|
||||
}
|
||||
if t.Signature.PublicKey == nil ||
|
||||
t.Signature.Signature == nil {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle merge")
|
||||
}
|
||||
if err := t.Signature.Verify(payload); err != nil {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle merge")
|
||||
}
|
||||
|
||||
addr, err := poseidon.HashBytes(t.Signature.PublicKey.KeyValue)
|
||||
|
||||
@ -29,7 +29,7 @@ func (a *TokenApplication) handleMint(
|
||||
frame *protobufs.ClockFrame,
|
||||
parallelismMap map[int]uint64,
|
||||
) ([]*protobufs.TokenOutput, error) {
|
||||
if t == nil || t.Proofs == nil || t.Signature == nil {
|
||||
if err := t.Validate(); err != nil {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle mint")
|
||||
}
|
||||
|
||||
@ -37,9 +37,7 @@ func (a *TokenApplication) handleMint(
|
||||
for _, p := range t.Proofs {
|
||||
payload = append(payload, p...)
|
||||
}
|
||||
if err := t.Signature.Verify(payload); err != nil {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle mint")
|
||||
}
|
||||
|
||||
pk, err := pcrypto.UnmarshalEd448PublicKey(
|
||||
t.Signature.PublicKey.KeyValue,
|
||||
)
|
||||
|
||||
@ -13,36 +13,14 @@ func (a *TokenApplication) handleAnnounce(
|
||||
[]*protobufs.TokenOutput,
|
||||
error,
|
||||
) {
|
||||
var primary *protobufs.Ed448Signature
|
||||
payload := []byte{}
|
||||
|
||||
if t == nil || t.PublicKeySignaturesEd448 == nil ||
|
||||
len(t.PublicKeySignaturesEd448) == 0 {
|
||||
if err := t.Validate(); err != nil {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle announce")
|
||||
}
|
||||
for i, p := range t.PublicKeySignaturesEd448 {
|
||||
|
||||
for _, p := range t.PublicKeySignaturesEd448 {
|
||||
if _, touched := lockMap[string(p.PublicKey.KeyValue)]; touched {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle announce")
|
||||
}
|
||||
|
||||
if p.PublicKey == nil || p.Signature == nil ||
|
||||
p.PublicKey.KeyValue == nil {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle announce")
|
||||
}
|
||||
if i == 0 {
|
||||
primary = p
|
||||
} else {
|
||||
payload = append(payload, p.PublicKey.KeyValue...)
|
||||
if err := p.Verify(primary.PublicKey.KeyValue); err != nil {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle announce")
|
||||
}
|
||||
}
|
||||
}
|
||||
if primary == nil {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle announce")
|
||||
}
|
||||
if err := primary.Verify(payload); err != nil {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle announce")
|
||||
}
|
||||
|
||||
for _, p := range t.PublicKeySignaturesEd448[1:] {
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
package application
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/iden3/go-iden3-crypto/poseidon"
|
||||
pcrypto "github.com/libp2p/go-libp2p/core/crypto"
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
@ -50,25 +48,7 @@ func (a *TokenApplication) handleDataAnnounceProverJoin(
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle join")
|
||||
}
|
||||
|
||||
payload := []byte("join")
|
||||
|
||||
if t == nil || t.PublicKeySignatureEd448 == nil {
|
||||
a.Logger.Debug("invalid data for join")
|
||||
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle join")
|
||||
}
|
||||
|
||||
if t.PublicKeySignatureEd448.PublicKey == nil ||
|
||||
t.PublicKeySignatureEd448.Signature == nil ||
|
||||
t.PublicKeySignatureEd448.PublicKey.KeyValue == nil ||
|
||||
t.Filter == nil || len(t.Filter) != 32 {
|
||||
a.Logger.Debug(
|
||||
"bad payload",
|
||||
zap.Uint64("given_frame_number", t.FrameNumber),
|
||||
zap.Uint64("current_frame_number", currentFrameNumber),
|
||||
zap.Int("filter_length", len(t.Filter)),
|
||||
)
|
||||
|
||||
if err := t.Validate(); err != nil {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle join")
|
||||
}
|
||||
|
||||
@ -79,13 +59,6 @@ func (a *TokenApplication) handleDataAnnounceProverJoin(
|
||||
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle join")
|
||||
}
|
||||
payload = binary.BigEndian.AppendUint64(payload, t.FrameNumber)
|
||||
payload = append(payload, t.Filter...)
|
||||
|
||||
if err := t.PublicKeySignatureEd448.Verify(payload); err != nil {
|
||||
a.Logger.Debug("can't verify signature")
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle join")
|
||||
}
|
||||
|
||||
address, err := a.getAddressFromSignature(t.PublicKeySignatureEd448)
|
||||
if err != nil {
|
||||
|
||||
@ -70,10 +70,6 @@ func TestHandleProverJoin(t *testing.T) {
|
||||
}
|
||||
|
||||
addr := addrBI.FillBytes(make([]byte, 32))
|
||||
payload := []byte("join")
|
||||
payload = binary.BigEndian.AppendUint64(payload, 0)
|
||||
payload = append(payload, bytes.Repeat([]byte{0xff}, 32)...)
|
||||
sig, _ := privKey.Sign(payload)
|
||||
wprover := qcrypto.NewWesolowskiFrameProver(app.Logger)
|
||||
gen, _, err := wprover.CreateDataGenesisFrame(
|
||||
p2p.GetBloomFilter(application.TOKEN_ADDRESS, 256, 3),
|
||||
@ -87,24 +83,17 @@ func TestHandleProverJoin(t *testing.T) {
|
||||
app.ClockStore.StageDataClockFrame(selbi.FillBytes(make([]byte, 32)), gen, txn)
|
||||
app.ClockStore.CommitDataClockFrame(gen.Filter, 0, selbi.FillBytes(make([]byte, 32)), app.Tries, txn, false)
|
||||
txn.Commit()
|
||||
join := &protobufs.AnnounceProverJoin{
|
||||
Filter: bytes.Repeat([]byte{0xff}, 32),
|
||||
FrameNumber: 0,
|
||||
}
|
||||
assert.NoError(t, join.SignED448(pubkey, privKey.Sign))
|
||||
assert.NoError(t, join.Validate())
|
||||
app, success, fail, err := app.ApplyTransitions(
|
||||
1,
|
||||
&protobufs.TokenRequests{
|
||||
Requests: []*protobufs.TokenRequest{
|
||||
&protobufs.TokenRequest{
|
||||
Request: &protobufs.TokenRequest_Join{
|
||||
Join: &protobufs.AnnounceProverJoin{
|
||||
Filter: bytes.Repeat([]byte{0xff}, 32),
|
||||
FrameNumber: 0,
|
||||
PublicKeySignatureEd448: &protobufs.Ed448Signature{
|
||||
Signature: sig,
|
||||
PublicKey: &protobufs.Ed448PublicKey{
|
||||
KeyValue: pubkey,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
join.TokenRequest(),
|
||||
},
|
||||
},
|
||||
false,
|
||||
@ -121,24 +110,17 @@ func TestHandleProverJoin(t *testing.T) {
|
||||
app.ClockStore.StageDataClockFrame(selbi.FillBytes(make([]byte, 32)), frame1, txn)
|
||||
app.ClockStore.CommitDataClockFrame(frame1.Filter, 1, selbi.FillBytes(make([]byte, 32)), app.Tries, txn, false)
|
||||
txn.Commit()
|
||||
join = &protobufs.AnnounceProverJoin{
|
||||
Filter: bytes.Repeat([]byte{0xff}, 32),
|
||||
FrameNumber: 0,
|
||||
}
|
||||
assert.NoError(t, join.SignED448(pubkey, privKey.Sign))
|
||||
assert.NoError(t, join.Validate())
|
||||
_, success, fail, err = app.ApplyTransitions(
|
||||
2,
|
||||
&protobufs.TokenRequests{
|
||||
Requests: []*protobufs.TokenRequest{
|
||||
&protobufs.TokenRequest{
|
||||
Request: &protobufs.TokenRequest_Join{
|
||||
Join: &protobufs.AnnounceProverJoin{
|
||||
Filter: bytes.Repeat([]byte{0xff}, 32),
|
||||
FrameNumber: 0,
|
||||
PublicKeySignatureEd448: &protobufs.Ed448Signature{
|
||||
Signature: sig,
|
||||
PublicKey: &protobufs.Ed448PublicKey{
|
||||
KeyValue: pubkey,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
join.TokenRequest(),
|
||||
},
|
||||
},
|
||||
false,
|
||||
@ -175,7 +157,7 @@ func TestHandleProverJoin(t *testing.T) {
|
||||
fmt.Printf("%x\n", individualChallenge)
|
||||
out2, _ := wprover.CalculateChallengeProof(individualChallenge, 10000)
|
||||
|
||||
proofTree, payload, output, err := tries.PackOutputIntoPayloadAndProof(
|
||||
proofTree, output, err := tries.PackOutputIntoPayloadAndProof(
|
||||
[]merkletree.DataBlock{tries.NewProofLeaf(out1), tries.NewProofLeaf(out2)},
|
||||
2,
|
||||
frame2,
|
||||
@ -183,22 +165,15 @@ func TestHandleProverJoin(t *testing.T) {
|
||||
)
|
||||
assert.NoError(t, err)
|
||||
|
||||
sig, _ = privKey.Sign(payload)
|
||||
mint := &protobufs.MintCoinRequest{
|
||||
Proofs: output,
|
||||
}
|
||||
assert.NoError(t, mint.SignED448(pubkey, privKey.Sign))
|
||||
assert.NoError(t, mint.Validate())
|
||||
|
||||
app, success, _, err = app.ApplyTransitions(2, &protobufs.TokenRequests{
|
||||
Requests: []*protobufs.TokenRequest{
|
||||
&protobufs.TokenRequest{
|
||||
Request: &protobufs.TokenRequest_Mint{
|
||||
Mint: &protobufs.MintCoinRequest{
|
||||
Proofs: output,
|
||||
Signature: &protobufs.Ed448Signature{
|
||||
PublicKey: &protobufs.Ed448PublicKey{
|
||||
KeyValue: pubkey,
|
||||
},
|
||||
Signature: sig,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
mint.TokenRequest(),
|
||||
},
|
||||
}, false)
|
||||
|
||||
@ -240,7 +215,7 @@ func TestHandleProverJoin(t *testing.T) {
|
||||
app.ClockStore.CommitDataClockFrame(frame3.Filter, 3, selbi.FillBytes(make([]byte, 32)), app.Tries, txn, false)
|
||||
txn.Commit()
|
||||
|
||||
proofTree, payload, output, err = tries.PackOutputIntoPayloadAndProof(
|
||||
proofTree, output, err = tries.PackOutputIntoPayloadAndProof(
|
||||
[]merkletree.DataBlock{tries.NewProofLeaf(out1), tries.NewProofLeaf(out2)},
|
||||
2,
|
||||
frame3,
|
||||
@ -248,22 +223,15 @@ func TestHandleProverJoin(t *testing.T) {
|
||||
)
|
||||
assert.NoError(t, err)
|
||||
|
||||
sig, _ = privKey.Sign(payload)
|
||||
mint = &protobufs.MintCoinRequest{
|
||||
Proofs: output,
|
||||
}
|
||||
assert.NoError(t, mint.SignED448(pubkey, privKey.Sign))
|
||||
assert.NoError(t, mint.Validate())
|
||||
|
||||
app, success, _, err = app.ApplyTransitions(3, &protobufs.TokenRequests{
|
||||
Requests: []*protobufs.TokenRequest{
|
||||
&protobufs.TokenRequest{
|
||||
Request: &protobufs.TokenRequest_Mint{
|
||||
Mint: &protobufs.MintCoinRequest{
|
||||
Proofs: output,
|
||||
Signature: &protobufs.Ed448Signature{
|
||||
PublicKey: &protobufs.Ed448PublicKey{
|
||||
KeyValue: pubkey,
|
||||
},
|
||||
Signature: sig,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
mint.TokenRequest(),
|
||||
},
|
||||
}, false)
|
||||
assert.NoError(t, err)
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
package application
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"source.quilibrium.com/quilibrium/monorepo/node/protobufs"
|
||||
)
|
||||
@ -19,17 +17,11 @@ func (a *TokenApplication) handleDataAnnounceProverLeave(
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle leave")
|
||||
}
|
||||
|
||||
payload := []byte("leave")
|
||||
|
||||
if t == nil || t.PublicKeySignatureEd448 == nil {
|
||||
if err := t.Validate(); err != nil {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle leave")
|
||||
}
|
||||
|
||||
if t.PublicKeySignatureEd448.PublicKey == nil ||
|
||||
t.PublicKeySignatureEd448.Signature == nil ||
|
||||
t.PublicKeySignatureEd448.PublicKey.KeyValue == nil ||
|
||||
t.Filter == nil || len(t.Filter) != 32 ||
|
||||
t.FrameNumber > currentFrameNumber {
|
||||
if t.FrameNumber > currentFrameNumber {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle leave")
|
||||
}
|
||||
|
||||
@ -39,13 +31,6 @@ func (a *TokenApplication) handleDataAnnounceProverLeave(
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle leave")
|
||||
}
|
||||
|
||||
payload = binary.BigEndian.AppendUint64(payload, t.FrameNumber)
|
||||
payload = append(payload, t.Filter...)
|
||||
|
||||
if err := t.PublicKeySignatureEd448.Verify(payload); err != nil {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle leave")
|
||||
}
|
||||
|
||||
address, err := a.getAddressFromSignature(t.PublicKeySignatureEd448)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "handle leave")
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
package application
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"source.quilibrium.com/quilibrium/monorepo/node/protobufs"
|
||||
)
|
||||
@ -19,17 +17,11 @@ func (a *TokenApplication) handleDataAnnounceProverPause(
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle pause")
|
||||
}
|
||||
|
||||
payload := []byte("pause")
|
||||
|
||||
if t == nil || t.PublicKeySignatureEd448 == nil {
|
||||
if err := t.Validate(); err != nil {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle pause")
|
||||
}
|
||||
|
||||
if t.PublicKeySignatureEd448.PublicKey == nil ||
|
||||
t.PublicKeySignatureEd448.Signature == nil ||
|
||||
t.PublicKeySignatureEd448.PublicKey.KeyValue == nil ||
|
||||
t.Filter == nil || len(t.Filter) != 32 ||
|
||||
t.FrameNumber > currentFrameNumber {
|
||||
if t.FrameNumber > currentFrameNumber {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle pause")
|
||||
}
|
||||
if _, touched := lockMap[string(
|
||||
@ -38,13 +30,6 @@ func (a *TokenApplication) handleDataAnnounceProverPause(
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle pause")
|
||||
}
|
||||
|
||||
payload = binary.BigEndian.AppendUint64(payload, t.FrameNumber)
|
||||
payload = append(payload, t.Filter...)
|
||||
|
||||
if err := t.PublicKeySignatureEd448.Verify(payload); err != nil {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle pause")
|
||||
}
|
||||
|
||||
address, err := a.getAddressFromSignature(t.PublicKeySignatureEd448)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "handle pause")
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
package application
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"source.quilibrium.com/quilibrium/monorepo/node/protobufs"
|
||||
)
|
||||
@ -19,17 +17,11 @@ func (a *TokenApplication) handleDataAnnounceProverResume(
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle resume")
|
||||
}
|
||||
|
||||
payload := []byte("resume")
|
||||
|
||||
if t == nil || t.PublicKeySignatureEd448 == nil {
|
||||
if err := t.Validate(); err != nil {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle resume")
|
||||
}
|
||||
|
||||
if t.PublicKeySignatureEd448.PublicKey == nil ||
|
||||
t.PublicKeySignatureEd448.Signature == nil ||
|
||||
t.PublicKeySignatureEd448.PublicKey.KeyValue == nil ||
|
||||
t.Filter == nil || len(t.Filter) != 32 ||
|
||||
t.FrameNumber > currentFrameNumber {
|
||||
if t.FrameNumber > currentFrameNumber {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle resume")
|
||||
}
|
||||
|
||||
@ -39,13 +31,6 @@ func (a *TokenApplication) handleDataAnnounceProverResume(
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle resume")
|
||||
}
|
||||
|
||||
payload = binary.BigEndian.AppendUint64(payload, t.FrameNumber)
|
||||
payload = append(payload, t.Filter...)
|
||||
|
||||
if err := t.PublicKeySignatureEd448.Verify(payload); err != nil {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle resume")
|
||||
}
|
||||
|
||||
address, err := a.getAddressFromSignature(t.PublicKeySignatureEd448)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "handle resume")
|
||||
|
||||
@ -16,13 +16,13 @@ func (a *TokenApplication) handleSplit(
|
||||
lockMap map[string]struct{},
|
||||
t *protobufs.SplitCoinRequest,
|
||||
) ([]*protobufs.TokenOutput, error) {
|
||||
newCoins := []*protobufs.Coin{}
|
||||
newAmounts := []*big.Int{}
|
||||
payload := []byte{}
|
||||
if t.Signature == nil || t.OfCoin == nil || t.OfCoin.Address == nil ||
|
||||
len(t.OfCoin.Address) != 32 {
|
||||
if err := t.Validate(); err != nil {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle split")
|
||||
}
|
||||
|
||||
newCoins := []*protobufs.Coin{}
|
||||
newAmounts := []*big.Int{}
|
||||
|
||||
coin, err := a.CoinStore.GetCoinByAddress(nil, t.OfCoin.Address)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle split")
|
||||
@ -32,24 +32,6 @@ func (a *TokenApplication) handleSplit(
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle split")
|
||||
}
|
||||
|
||||
payload = append(payload, []byte("split")...)
|
||||
payload = append(payload, t.OfCoin.Address...)
|
||||
|
||||
if len(t.Amounts) > 100 {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle split")
|
||||
}
|
||||
|
||||
for _, a := range t.Amounts {
|
||||
if len(a) > 32 {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle split")
|
||||
}
|
||||
payload = append(payload, a...)
|
||||
}
|
||||
|
||||
if err := t.Signature.Verify(payload); err != nil {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle split")
|
||||
}
|
||||
|
||||
addr, err := poseidon.HashBytes(t.Signature.PublicKey.KeyValue)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle split")
|
||||
|
||||
@ -16,12 +16,7 @@ func (a *TokenApplication) handleTransfer(
|
||||
lockMap map[string]struct{},
|
||||
t *protobufs.TransferCoinRequest,
|
||||
) ([]*protobufs.TokenOutput, error) {
|
||||
payload := []byte("transfer")
|
||||
if t == nil || t.Signature == nil || t.OfCoin == nil ||
|
||||
t.OfCoin.Address == nil || len(t.OfCoin.Address) != 32 ||
|
||||
t.ToAccount == nil || t.ToAccount.GetImplicitAccount() == nil ||
|
||||
t.ToAccount.GetImplicitAccount().Address == nil ||
|
||||
len(t.ToAccount.GetImplicitAccount().Address) != 32 {
|
||||
if err := t.Validate(); err != nil {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle transfer")
|
||||
}
|
||||
|
||||
@ -34,16 +29,6 @@ func (a *TokenApplication) handleTransfer(
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle transfer")
|
||||
}
|
||||
|
||||
payload = append(payload, t.OfCoin.Address...)
|
||||
payload = append(
|
||||
payload,
|
||||
t.ToAccount.GetImplicitAccount().Address...,
|
||||
)
|
||||
|
||||
if err := t.Signature.Verify(payload); err != nil {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle transfer")
|
||||
}
|
||||
|
||||
addr, err := poseidon.HashBytes(t.Signature.PublicKey.KeyValue)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ErrInvalidStateTransition, "handle transfer")
|
||||
|
||||
@ -4,7 +4,6 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"math/big"
|
||||
"slices"
|
||||
@ -83,6 +82,7 @@ func (p PeerSeniorityItem) Priority() uint64 {
|
||||
type TokenExecutionEngine struct {
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
wg sync.WaitGroup
|
||||
logger *zap.Logger
|
||||
clock *data.DataClockConsensusEngine
|
||||
clockStore store.ClockStore
|
||||
@ -341,7 +341,9 @@ func NewTokenExecutionEngine(
|
||||
e.proverPublicKey = publicKeyBytes
|
||||
e.provingKeyAddress = provingKeyAddress
|
||||
|
||||
e.wg.Add(1)
|
||||
go func() {
|
||||
defer e.wg.Done()
|
||||
f, tries, err := e.clockStore.GetLatestDataClockFrame(e.intrinsicFilter)
|
||||
if err != nil {
|
||||
return
|
||||
@ -361,11 +363,14 @@ func NewTokenExecutionEngine(
|
||||
}
|
||||
|
||||
if shouldResume {
|
||||
msg := []byte("resume")
|
||||
msg = binary.BigEndian.AppendUint64(msg, f.FrameNumber)
|
||||
msg = append(msg, e.intrinsicFilter...)
|
||||
sig, err := e.pubSub.SignMessage(msg)
|
||||
if err != nil {
|
||||
resume := &protobufs.AnnounceProverResume{
|
||||
Filter: e.intrinsicFilter,
|
||||
FrameNumber: f.FrameNumber,
|
||||
}
|
||||
if err := resume.SignED448(e.pubSub.GetPublicKey(), e.pubSub.SignMessage); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := resume.Validate(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -388,21 +393,7 @@ func NewTokenExecutionEngine(
|
||||
}
|
||||
e.publishMessage(
|
||||
append([]byte{0x00}, e.intrinsicFilter...),
|
||||
&protobufs.TokenRequest{
|
||||
Request: &protobufs.TokenRequest_Resume{
|
||||
Resume: &protobufs.AnnounceProverResume{
|
||||
Filter: e.intrinsicFilter,
|
||||
FrameNumber: f.FrameNumber,
|
||||
PublicKeySignatureEd448: &protobufs.Ed448Signature{
|
||||
PublicKey: &protobufs.Ed448PublicKey{
|
||||
KeyValue: e.pubSub.GetPublicKey(),
|
||||
},
|
||||
Signature: sig,
|
||||
},
|
||||
},
|
||||
},
|
||||
Timestamp: gotime.Now().UnixMilli(),
|
||||
},
|
||||
resume.TokenRequest(),
|
||||
)
|
||||
}
|
||||
}()
|
||||
@ -453,6 +444,7 @@ func (e *TokenExecutionEngine) Start() <-chan error {
|
||||
// Stop implements ExecutionEngine
|
||||
func (e *TokenExecutionEngine) Stop(force bool) <-chan error {
|
||||
e.cancel()
|
||||
e.wg.Wait()
|
||||
|
||||
errChan := make(chan error)
|
||||
|
||||
@ -469,20 +461,20 @@ func (e *TokenExecutionEngine) ProcessMessage(
|
||||
message *protobufs.Message,
|
||||
) ([]*protobufs.Message, error) {
|
||||
if bytes.Equal(address, e.GetSupportedApplications()[0].Address) {
|
||||
any := &anypb.Any{}
|
||||
if err := proto.Unmarshal(message.Payload, any); err != nil {
|
||||
a := &anypb.Any{}
|
||||
if err := proto.Unmarshal(message.Payload, a); err != nil {
|
||||
return nil, errors.Wrap(err, "process message")
|
||||
}
|
||||
|
||||
e.logger.Debug(
|
||||
"processing execution message",
|
||||
zap.String("type", any.TypeUrl),
|
||||
zap.String("type", a.TypeUrl),
|
||||
)
|
||||
|
||||
switch any.TypeUrl {
|
||||
switch a.TypeUrl {
|
||||
case protobufs.TokenRequestType:
|
||||
if e.clock.IsInProverTrie(e.proverPublicKey) {
|
||||
payload, err := proto.Marshal(any)
|
||||
payload, err := proto.Marshal(a)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "process message")
|
||||
}
|
||||
@ -1109,19 +1101,19 @@ func (e *TokenExecutionEngine) publishMessage(
|
||||
filter []byte,
|
||||
message proto.Message,
|
||||
) error {
|
||||
any := &anypb.Any{}
|
||||
if err := any.MarshalFrom(message); err != nil {
|
||||
a := &anypb.Any{}
|
||||
if err := a.MarshalFrom(message); err != nil {
|
||||
return errors.Wrap(err, "publish message")
|
||||
}
|
||||
|
||||
any.TypeUrl = strings.Replace(
|
||||
any.TypeUrl,
|
||||
a.TypeUrl = strings.Replace(
|
||||
a.TypeUrl,
|
||||
"type.googleapis.com",
|
||||
"types.quilibrium.com",
|
||||
1,
|
||||
)
|
||||
|
||||
payload, err := proto.Marshal(any)
|
||||
payload, err := proto.Marshal(a)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "publish message")
|
||||
}
|
||||
@ -1373,8 +1365,14 @@ func (e *TokenExecutionEngine) AnnounceProverMerge() *protobufs.AnnounceProverRe
|
||||
currentHead.FrameNumber < application.PROOF_FRAME_CUTOFF {
|
||||
return nil
|
||||
}
|
||||
keys := [][]byte{}
|
||||
ksigs := [][]byte{}
|
||||
|
||||
var helpers []protobufs.ED448SignHelper = []protobufs.ED448SignHelper{
|
||||
{
|
||||
PublicKey: e.pubSub.GetPublicKey(),
|
||||
Sign: e.pubSub.SignMessage,
|
||||
},
|
||||
}
|
||||
|
||||
if len(e.engineConfig.MultisigProverEnrollmentPaths) != 0 &&
|
||||
e.GetSeniority().Cmp(GetAggregatedSeniority(
|
||||
[]string{peer.ID(e.pubSub.GetPeerID()).String()},
|
||||
@ -1401,86 +1399,46 @@ func (e *TokenExecutionEngine) AnnounceProverMerge() *protobufs.AnnounceProverRe
|
||||
panic(errors.Wrap(err, "error unmarshaling peerkey"))
|
||||
}
|
||||
|
||||
keys = append(keys, pubBytes)
|
||||
sig, err := privKey.Sign(e.pubSub.GetPublicKey())
|
||||
if err != nil {
|
||||
panic(errors.Wrap(err, "error unmarshaling peerkey"))
|
||||
}
|
||||
ksigs = append(ksigs, sig)
|
||||
helpers = append(helpers, protobufs.ED448SignHelper{
|
||||
PublicKey: pubBytes,
|
||||
Sign: privKey.Sign,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
keyjoin := []byte{}
|
||||
for _, k := range keys {
|
||||
keyjoin = append(keyjoin, k...)
|
||||
}
|
||||
|
||||
mainsig, err := e.pubSub.SignMessage(keyjoin)
|
||||
if err != nil {
|
||||
announce := &protobufs.AnnounceProverRequest{}
|
||||
if err := announce.SignED448(helpers); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
announce := &protobufs.AnnounceProverRequest{
|
||||
PublicKeySignaturesEd448: []*protobufs.Ed448Signature{},
|
||||
}
|
||||
|
||||
announce.PublicKeySignaturesEd448 = append(
|
||||
announce.PublicKeySignaturesEd448,
|
||||
&protobufs.Ed448Signature{
|
||||
PublicKey: &protobufs.Ed448PublicKey{
|
||||
KeyValue: e.pubSub.GetPublicKey(),
|
||||
},
|
||||
Signature: mainsig,
|
||||
},
|
||||
)
|
||||
|
||||
for i := range keys {
|
||||
announce.PublicKeySignaturesEd448 = append(
|
||||
announce.PublicKeySignaturesEd448,
|
||||
&protobufs.Ed448Signature{
|
||||
PublicKey: &protobufs.Ed448PublicKey{
|
||||
KeyValue: keys[i],
|
||||
},
|
||||
Signature: ksigs[i],
|
||||
},
|
||||
)
|
||||
if err := announce.Validate(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return announce
|
||||
}
|
||||
|
||||
func (e *TokenExecutionEngine) AnnounceProverJoin() {
|
||||
msg := []byte("join")
|
||||
head := e.GetFrame()
|
||||
if head == nil ||
|
||||
head.FrameNumber < application.PROOF_FRAME_CUTOFF {
|
||||
return
|
||||
}
|
||||
msg = binary.BigEndian.AppendUint64(msg, head.FrameNumber)
|
||||
msg = append(msg, bytes.Repeat([]byte{0xff}, 32)...)
|
||||
sig, err := e.pubSub.SignMessage(msg)
|
||||
if err != nil {
|
||||
|
||||
join := &protobufs.AnnounceProverJoin{
|
||||
Filter: bytes.Repeat([]byte{0xff}, 32),
|
||||
FrameNumber: head.FrameNumber,
|
||||
Announce: e.AnnounceProverMerge(),
|
||||
}
|
||||
if err := join.SignED448(e.pubSub.GetPublicKey(), e.pubSub.SignMessage); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := join.Validate(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
e.publishMessage(
|
||||
append([]byte{0x00}, e.intrinsicFilter...),
|
||||
&protobufs.TokenRequest{
|
||||
Request: &protobufs.TokenRequest_Join{
|
||||
Join: &protobufs.AnnounceProverJoin{
|
||||
Filter: bytes.Repeat([]byte{0xff}, 32),
|
||||
FrameNumber: head.FrameNumber,
|
||||
PublicKeySignatureEd448: &protobufs.Ed448Signature{
|
||||
Signature: sig,
|
||||
PublicKey: &protobufs.Ed448PublicKey{
|
||||
KeyValue: e.pubSub.GetPublicKey(),
|
||||
},
|
||||
},
|
||||
Announce: e.AnnounceProverMerge(),
|
||||
},
|
||||
},
|
||||
Timestamp: gotime.Now().UnixMilli(),
|
||||
},
|
||||
join.TokenRequest(),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
module source.quilibrium.com/quilibrium/monorepo/node
|
||||
|
||||
go 1.21
|
||||
go 1.22
|
||||
|
||||
toolchain go1.22.1
|
||||
toolchain go1.22.5
|
||||
|
||||
// A necessary hack until source.quilibrium.com is open to all
|
||||
replace source.quilibrium.com/quilibrium/monorepo/nekryptology => ../nekryptology
|
||||
@ -15,6 +15,8 @@ replace github.com/multiformats/go-multiaddr => ../go-multiaddr
|
||||
|
||||
replace github.com/multiformats/go-multiaddr-dns => ../go-multiaddr-dns
|
||||
|
||||
replace github.com/libp2p/go-buffer-pool => ../go-buffer-pool
|
||||
|
||||
replace github.com/libp2p/go-libp2p => ../go-libp2p
|
||||
|
||||
replace github.com/libp2p/go-libp2p-kad-dht => ../go-libp2p-kad-dht
|
||||
|
||||
@ -275,8 +275,6 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c=
|
||||
github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8=
|
||||
github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8=
|
||||
github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg=
|
||||
github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c=
|
||||
github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic=
|
||||
github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM=
|
||||
|
||||
@ -6,6 +6,7 @@ import (
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"math"
|
||||
"math/big"
|
||||
"math/bits"
|
||||
"net"
|
||||
@ -60,8 +61,15 @@ const (
|
||||
defaultPingTimeout = 5 * time.Second
|
||||
defaultPingPeriod = 30 * time.Second
|
||||
defaultPingAttempts = 3
|
||||
DecayInterval = 10 * time.Second
|
||||
AppDecay = .9
|
||||
)
|
||||
|
||||
type appScore struct {
|
||||
expire time.Time
|
||||
score float64
|
||||
}
|
||||
|
||||
type BlossomSub struct {
|
||||
ps *blossomsub.PubSub
|
||||
ctx context.Context
|
||||
@ -70,7 +78,7 @@ type BlossomSub struct {
|
||||
bitmaskMap map[string]*blossomsub.Bitmask
|
||||
h host.Host
|
||||
signKey crypto.PrivKey
|
||||
peerScore map[string]int64
|
||||
peerScore map[string]*appScore
|
||||
peerScoreMx sync.Mutex
|
||||
network uint8
|
||||
bootstrap internal.PeerConnector
|
||||
@ -148,7 +156,7 @@ func NewBlossomSubStreamer(
|
||||
logger: logger,
|
||||
bitmaskMap: make(map[string]*blossomsub.Bitmask),
|
||||
signKey: privKey,
|
||||
peerScore: make(map[string]int64),
|
||||
peerScore: make(map[string]*appScore),
|
||||
network: p2pConfig.Network,
|
||||
}
|
||||
|
||||
@ -302,7 +310,7 @@ func NewBlossomSub(
|
||||
logger: logger,
|
||||
bitmaskMap: make(map[string]*blossomsub.Bitmask),
|
||||
signKey: privKey,
|
||||
peerScore: make(map[string]int64),
|
||||
peerScore: make(map[string]*appScore),
|
||||
network: p2pConfig.Network,
|
||||
}
|
||||
|
||||
@ -443,7 +451,7 @@ func NewBlossomSub(
|
||||
BehaviourPenaltyWeight: -10,
|
||||
BehaviourPenaltyThreshold: 100,
|
||||
BehaviourPenaltyDecay: .5,
|
||||
DecayInterval: 10 * time.Second,
|
||||
DecayInterval: DecayInterval,
|
||||
DecayToZero: .1,
|
||||
RetainScore: 60 * time.Minute,
|
||||
AppSpecificScore: func(p peer.ID) float64 {
|
||||
@ -493,6 +501,8 @@ func NewBlossomSub(
|
||||
bs.h = h
|
||||
bs.signKey = privKey
|
||||
|
||||
go bs.background(ctx)
|
||||
|
||||
return bs
|
||||
}
|
||||
|
||||
@ -586,6 +596,39 @@ func resourceManager(highWatermark int, allowed []peer.AddrInfo) (
|
||||
return mgr, nil
|
||||
}
|
||||
|
||||
func (b *BlossomSub) background(ctx context.Context) {
|
||||
refreshScores := time.NewTicker(DecayInterval)
|
||||
defer refreshScores.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-refreshScores.C:
|
||||
b.refreshScores()
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (b *BlossomSub) refreshScores() {
|
||||
b.peerScoreMx.Lock()
|
||||
|
||||
now := time.Now()
|
||||
for p, pstats := range b.peerScore {
|
||||
if now.After(pstats.expire) {
|
||||
delete(b.peerScore, p)
|
||||
continue
|
||||
}
|
||||
|
||||
pstats.score *= AppDecay
|
||||
if math.Abs(pstats.score) < .1 {
|
||||
pstats.score = 0
|
||||
}
|
||||
}
|
||||
|
||||
b.peerScoreMx.Unlock()
|
||||
}
|
||||
|
||||
func (b *BlossomSub) PublishToBitmask(bitmask []byte, data []byte) error {
|
||||
return b.ps.Publish(b.ctx, bitmask, data)
|
||||
}
|
||||
@ -768,23 +811,37 @@ func (b *BlossomSub) DiscoverPeers(ctx context.Context) error {
|
||||
|
||||
func (b *BlossomSub) GetPeerScore(peerId []byte) int64 {
|
||||
b.peerScoreMx.Lock()
|
||||
score := b.peerScore[string(peerId)]
|
||||
peerScore, ok := b.peerScore[string(peerId)]
|
||||
if !ok {
|
||||
b.peerScoreMx.Unlock()
|
||||
return 0
|
||||
}
|
||||
score := peerScore.score
|
||||
b.peerScoreMx.Unlock()
|
||||
return score
|
||||
return int64(score)
|
||||
}
|
||||
|
||||
func (b *BlossomSub) SetPeerScore(peerId []byte, score int64) {
|
||||
b.peerScoreMx.Lock()
|
||||
b.peerScore[string(peerId)] = score
|
||||
b.peerScore[string(peerId)] = &appScore{
|
||||
score: float64(score),
|
||||
expire: time.Now().Add(1 * time.Hour),
|
||||
}
|
||||
b.peerScoreMx.Unlock()
|
||||
}
|
||||
|
||||
func (b *BlossomSub) AddPeerScore(peerId []byte, scoreDelta int64) {
|
||||
b.peerScoreMx.Lock()
|
||||
if _, ok := b.peerScore[string(peerId)]; !ok {
|
||||
b.peerScore[string(peerId)] = scoreDelta
|
||||
b.peerScore[string(peerId)] = &appScore{
|
||||
score: float64(scoreDelta),
|
||||
expire: time.Now().Add(1 * time.Hour),
|
||||
}
|
||||
} else {
|
||||
b.peerScore[string(peerId)] = b.peerScore[string(peerId)] + scoreDelta
|
||||
b.peerScore[string(peerId)] = &appScore{
|
||||
score: b.peerScore[string(peerId)].score + float64(scoreDelta),
|
||||
expire: time.Now().Add(1 * time.Hour),
|
||||
}
|
||||
}
|
||||
b.peerScoreMx.Unlock()
|
||||
}
|
||||
@ -979,6 +1036,9 @@ func withDefaults(p2pConfig *config.P2PConfig) *config.P2PConfig {
|
||||
if p2pConfig.DLazy == 0 {
|
||||
p2pConfig.DLazy = blossomsub.BlossomSubDlazy
|
||||
}
|
||||
if p2pConfig.GossipFactor == 0 {
|
||||
p2pConfig.GossipFactor = blossomsub.BlossomSubGossipFactor
|
||||
}
|
||||
if p2pConfig.GossipRetransmission == 0 {
|
||||
p2pConfig.GossipRetransmission = blossomsub.BlossomSubGossipRetransmission
|
||||
}
|
||||
@ -1091,6 +1151,7 @@ func toBlossomSubParams(p2pConfig *config.P2PConfig) blossomsub.BlossomSubParams
|
||||
HistoryLength: p2pConfig.HistoryLength,
|
||||
HistoryGossip: p2pConfig.HistoryGossip,
|
||||
Dlazy: p2pConfig.DLazy,
|
||||
GossipFactor: p2pConfig.GossipFactor,
|
||||
GossipRetransmission: p2pConfig.GossipRetransmission,
|
||||
HeartbeatInitialDelay: p2pConfig.HeartbeatInitialDelay,
|
||||
HeartbeatInterval: p2pConfig.HeartbeatInterval,
|
||||
|
||||
@ -78,6 +78,7 @@ type DataPeer struct {
|
||||
Timestamp int64 `protobuf:"varint,4,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
|
||||
Version []byte `protobuf:"bytes,5,opt,name=version,proto3" json:"version,omitempty"`
|
||||
TotalDistance []byte `protobuf:"bytes,8,opt,name=total_distance,json=totalDistance,proto3" json:"total_distance,omitempty"`
|
||||
PatchVersion []byte `protobuf:"bytes,9,opt,name=patch_version,json=patchVersion,proto3" json:"patch_version,omitempty"`
|
||||
}
|
||||
|
||||
func (x *DataPeer) Reset() {
|
||||
@ -154,6 +155,13 @@ func (x *DataPeer) GetTotalDistance() []byte {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *DataPeer) GetPatchVersion() []byte {
|
||||
if x != nil {
|
||||
return x.PatchVersion
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type DataCompressedSync struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@ -1087,7 +1095,7 @@ var file_data_proto_rawDesc = []byte{
|
||||
0x21, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64,
|
||||
0x65, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x62, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x50, 0x65,
|
||||
0x65, 0x72, 0x52, 0x04, 0x70, 0x65, 0x65, 0x72, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x52, 0x09,
|
||||
0x70, 0x65, 0x65, 0x72, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x22, 0xe0, 0x01, 0x0a, 0x08, 0x44, 0x61,
|
||||
0x70, 0x65, 0x65, 0x72, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x22, 0x85, 0x02, 0x0a, 0x08, 0x44, 0x61,
|
||||
0x74, 0x61, 0x50, 0x65, 0x65, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x69,
|
||||
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x70, 0x65, 0x65, 0x72, 0x49, 0x64, 0x12,
|
||||
0x1c, 0x0a, 0x09, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01,
|
||||
@ -1099,204 +1107,206 @@ var file_data_proto_rawDesc = []byte{
|
||||
0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69,
|
||||
0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x64, 0x69, 0x73, 0x74,
|
||||
0x61, 0x6e, 0x63, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x74, 0x6f, 0x74, 0x61,
|
||||
0x6c, 0x44, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x4a, 0x04, 0x08, 0x06, 0x10, 0x07, 0x4a,
|
||||
0x04, 0x08, 0x07, 0x10, 0x08, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65,
|
||||
0x52, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x22, 0xd4, 0x02, 0x0a,
|
||||
0x12, 0x44, 0x61, 0x74, 0x61, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x53,
|
||||
0x79, 0x6e, 0x63, 0x12, 0x2a, 0x0a, 0x11, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x66, 0x72, 0x61, 0x6d,
|
||||
0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f,
|
||||
0x66, 0x72, 0x6f, 0x6d, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12,
|
||||
0x26, 0x0a, 0x0f, 0x74, 0x6f, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x62,
|
||||
0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, 0x6f, 0x46, 0x72, 0x61, 0x6d,
|
||||
0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x5a, 0x0a, 0x16, 0x74, 0x72, 0x75, 0x6e, 0x63,
|
||||
0x61, 0x74, 0x65, 0x64, 0x5f, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65,
|
||||
0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62,
|
||||
0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x2e,
|
||||
0x70, 0x62, 0x2e, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x52, 0x14, 0x74,
|
||||
0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x64, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x72, 0x61,
|
||||
0x6d, 0x65, 0x73, 0x12, 0x43, 0x0a, 0x06, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x18, 0x04, 0x20,
|
||||
0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d,
|
||||
0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x62, 0x2e, 0x49, 0x6e,
|
||||
0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x4d, 0x61, 0x70,
|
||||
0x52, 0x06, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x12, 0x49, 0x0a, 0x08, 0x73, 0x65, 0x67, 0x6d,
|
||||
0x65, 0x6e, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x71, 0x75, 0x69,
|
||||
0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x64, 0x61, 0x74,
|
||||
0x61, 0x2e, 0x70, 0x62, 0x2e, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x65,
|
||||
0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x4d, 0x61, 0x70, 0x52, 0x08, 0x73, 0x65, 0x67, 0x6d, 0x65,
|
||||
0x6e, 0x74, 0x73, 0x22, 0x97, 0x01, 0x0a, 0x19, 0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x0c, 0x52, 0x06, 0x70, 0x65, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x68,
|
||||
0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63,
|
||||
0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x12, 0x43, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x71, 0x75, 0x69,
|
||||
0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6b, 0x65, 0x79,
|
||||
0x73, 0x2e, 0x70, 0x62, 0x2e, 0x45, 0x64, 0x34, 0x34, 0x38, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74,
|
||||
0x75, 0x72, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xaa, 0x02,
|
||||
0x0a, 0x20, 0x44, 0x61, 0x74, 0x61, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64,
|
||||
0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61,
|
||||
0x67, 0x65, 0x12, 0x4e, 0x0a, 0x09, 0x70, 0x72, 0x65, 0x66, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69,
|
||||
0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x70, 0x62,
|
||||
0x2e, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x50, 0x72, 0x65, 0x66,
|
||||
0x6c, 0x69, 0x67, 0x68, 0x74, 0x48, 0x00, 0x52, 0x09, 0x70, 0x72, 0x65, 0x66, 0x6c, 0x69, 0x67,
|
||||
0x68, 0x74, 0x12, 0x48, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d,
|
||||
0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x70, 0x62, 0x2e, 0x43,
|
||||
0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x48, 0x00, 0x52, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x5c, 0x0a, 0x0e,
|
||||
0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75,
|
||||
0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x62, 0x2e, 0x53,
|
||||
0x79, 0x6e, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e,
|
||||
0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x0e, 0x61, 0x75, 0x74, 0x68,
|
||||
0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x0e, 0x0a, 0x0c, 0x73, 0x79,
|
||||
0x6e, 0x63, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xce, 0x01, 0x0a, 0x21, 0x44,
|
||||
0x61, 0x74, 0x61, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x53, 0x79, 0x6e,
|
||||
0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
|
||||
0x12, 0x4e, 0x0a, 0x09, 0x70, 0x72, 0x65, 0x66, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d,
|
||||
0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x70, 0x62, 0x2e, 0x43,
|
||||
0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x50, 0x72, 0x65, 0x66, 0x6c, 0x69,
|
||||
0x67, 0x68, 0x74, 0x48, 0x00, 0x52, 0x09, 0x70, 0x72, 0x65, 0x66, 0x6c, 0x69, 0x67, 0x68, 0x74,
|
||||
0x12, 0x49, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e,
|
||||
0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x62, 0x2e, 0x44, 0x61, 0x74,
|
||||
0x61, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x53, 0x79, 0x6e, 0x63, 0x48,
|
||||
0x00, 0x52, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x0e, 0x0a, 0x0c, 0x73,
|
||||
0x79, 0x6e, 0x63, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xa1, 0x01, 0x0a, 0x12,
|
||||
0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x4d,
|
||||
0x61, 0x70, 0x12, 0x21, 0x0a, 0x0c, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x5f, 0x63, 0x6f, 0x6d, 0x6d,
|
||||
0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x43,
|
||||
0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x52, 0x0a, 0x0b, 0x63,
|
||||
0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b,
|
||||
0x32, 0x30, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f,
|
||||
0x64, 0x65, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x62, 0x2e, 0x49, 0x6e, 0x63, 0x6c, 0x75,
|
||||
0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x4d,
|
||||
0x61, 0x70, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22,
|
||||
0x3e, 0x0a, 0x14, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x67, 0x6d,
|
||||
0x65, 0x6e, 0x74, 0x73, 0x4d, 0x61, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x64,
|
||||
0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22,
|
||||
0x7b, 0x0a, 0x17, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6d, 0x6d,
|
||||
0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x4d, 0x61, 0x70, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f,
|
||||
0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a,
|
||||
0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x79,
|
||||
0x70, 0x65, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x79,
|
||||
0x70, 0x65, 0x55, 0x72, 0x6c, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74,
|
||||
0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0d, 0x73,
|
||||
0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x22, 0x51, 0x0a, 0x13,
|
||||
0x47, 0x65, 0x74, 0x44, 0x61, 0x74, 0x61, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x5f, 0x6e, 0x75, 0x6d,
|
||||
0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x66, 0x72, 0x61, 0x6d, 0x65,
|
||||
0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x69,
|
||||
0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x65, 0x65, 0x72, 0x49, 0x64, 0x22,
|
||||
0x70, 0x0a, 0x11, 0x44, 0x61, 0x74, 0x61, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x0b, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x66, 0x72,
|
||||
0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x71, 0x75, 0x69, 0x6c,
|
||||
0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x63,
|
||||
0x6b, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x52,
|
||||
0x0a, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x70,
|
||||
0x72, 0x6f, 0x6f, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x70, 0x72, 0x6f, 0x6f,
|
||||
0x66, 0x22, 0x51, 0x0a, 0x17, 0x50, 0x72, 0x65, 0x4d, 0x69, 0x64, 0x6e, 0x69, 0x67, 0x68, 0x74,
|
||||
0x4d, 0x69, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07,
|
||||
0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61,
|
||||
0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x6d,
|
||||
0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x69, 0x6e, 0x63, 0x72, 0x65,
|
||||
0x6d, 0x65, 0x6e, 0x74, 0x22, 0x34, 0x0a, 0x1c, 0x50, 0x72, 0x65, 0x4d, 0x69, 0x64, 0x6e, 0x69,
|
||||
0x67, 0x68, 0x74, 0x4d, 0x69, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x0c, 0x52, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x22, 0x97, 0x01, 0x0a, 0x10, 0x46,
|
||||
0x72, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x62, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x12,
|
||||
0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x66,
|
||||
0x72, 0x6f, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52,
|
||||
0x02, 0x74, 0x6f, 0x12, 0x47, 0x0a, 0x0c, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x66, 0x72, 0x61,
|
||||
0x6d, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x71, 0x75, 0x69, 0x6c,
|
||||
0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x63,
|
||||
0x6b, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x52,
|
||||
0x0b, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06,
|
||||
0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x72, 0x61,
|
||||
0x6e, 0x64, 0x6f, 0x6d, 0x22, 0xe6, 0x01, 0x0a, 0x15, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e,
|
||||
0x67, 0x65, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17,
|
||||
0x0a, 0x07, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52,
|
||||
0x06, 0x70, 0x65, 0x65, 0x72, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x72, 0x65, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x63, 0x6f, 0x72, 0x65, 0x12, 0x45, 0x0a, 0x0b, 0x63,
|
||||
0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x24, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f,
|
||||
0x64, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x6f, 0x63,
|
||||
0x6b, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x52, 0x0a, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x72, 0x61,
|
||||
0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x04, 0x20, 0x01,
|
||||
0x28, 0x0c, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x66, 0x72,
|
||||
0x61, 0x6d, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04,
|
||||
0x52, 0x0b, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1e, 0x0a,
|
||||
0x0a, 0x64, 0x69, 0x66, 0x66, 0x69, 0x63, 0x75, 0x6c, 0x74, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28,
|
||||
0x0d, 0x52, 0x0a, 0x64, 0x69, 0x66, 0x66, 0x69, 0x63, 0x75, 0x6c, 0x74, 0x79, 0x22, 0x30, 0x0a,
|
||||
0x16, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75,
|
||||
0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x32,
|
||||
0xff, 0x05, 0x0a, 0x0b, 0x44, 0x61, 0x74, 0x61, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12,
|
||||
0x76, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64,
|
||||
0x53, 0x79, 0x6e, 0x63, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x2c, 0x2e, 0x71, 0x75, 0x69,
|
||||
0x6c, 0x44, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x61, 0x74,
|
||||
0x63, 0x68, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c,
|
||||
0x52, 0x0c, 0x70, 0x61, 0x74, 0x63, 0x68, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4a, 0x04,
|
||||
0x08, 0x06, 0x10, 0x07, 0x4a, 0x04, 0x08, 0x07, 0x10, 0x08, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e,
|
||||
0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65,
|
||||
0x79, 0x22, 0xd4, 0x02, 0x0a, 0x12, 0x44, 0x61, 0x74, 0x61, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65,
|
||||
0x73, 0x73, 0x65, 0x64, 0x53, 0x79, 0x6e, 0x63, 0x12, 0x2a, 0x0a, 0x11, 0x66, 0x72, 0x6f, 0x6d,
|
||||
0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x04, 0x52, 0x0f, 0x66, 0x72, 0x6f, 0x6d, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x4e, 0x75,
|
||||
0x6d, 0x62, 0x65, 0x72, 0x12, 0x26, 0x0a, 0x0f, 0x74, 0x6f, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65,
|
||||
0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74,
|
||||
0x6f, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x5a, 0x0a, 0x16,
|
||||
0x74, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x5f,
|
||||
0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x71,
|
||||
0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x63,
|
||||
0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x72, 0x61,
|
||||
0x6d, 0x65, 0x52, 0x14, 0x74, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x64, 0x43, 0x6c, 0x6f,
|
||||
0x63, 0x6b, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x43, 0x0a, 0x06, 0x70, 0x72, 0x6f, 0x6f,
|
||||
0x66, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69,
|
||||
0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e,
|
||||
0x70, 0x62, 0x2e, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x6f,
|
||||
0x66, 0x73, 0x4d, 0x61, 0x70, 0x52, 0x06, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x12, 0x49, 0x0a,
|
||||
0x08, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32,
|
||||
0x2d, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64,
|
||||
0x65, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x62, 0x2e, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x4d, 0x61, 0x70, 0x52, 0x08,
|
||||
0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x97, 0x01, 0x0a, 0x19, 0x53, 0x79, 0x6e,
|
||||
0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69,
|
||||
0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x69,
|
||||
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x70, 0x65, 0x65, 0x72, 0x49, 0x64, 0x12,
|
||||
0x1c, 0x0a, 0x09, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x0c, 0x52, 0x09, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x12, 0x43, 0x0a,
|
||||
0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||
0x27, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64,
|
||||
0x65, 0x2e, 0x6b, 0x65, 0x79, 0x73, 0x2e, 0x70, 0x62, 0x2e, 0x45, 0x64, 0x34, 0x34, 0x38, 0x53,
|
||||
0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x22, 0xaa, 0x02, 0x0a, 0x20, 0x44, 0x61, 0x74, 0x61, 0x43, 0x6f, 0x6d, 0x70, 0x72,
|
||||
0x65, 0x73, 0x73, 0x65, 0x64, 0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x4e, 0x0a, 0x09, 0x70, 0x72, 0x65, 0x66, 0x6c,
|
||||
0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x71, 0x75, 0x69,
|
||||
0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x63, 0x6c, 0x6f,
|
||||
0x63, 0x6b, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x72, 0x61, 0x6d, 0x65,
|
||||
0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69,
|
||||
0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e,
|
||||
0x70, 0x62, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65,
|
||||
0x64, 0x53, 0x79, 0x6e, 0x63, 0x30, 0x01, 0x12, 0x9a, 0x01, 0x0a, 0x1d, 0x4e, 0x65, 0x67, 0x6f,
|
||||
0x74, 0x69, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x53,
|
||||
0x79, 0x6e, 0x63, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x39, 0x2e, 0x71, 0x75, 0x69, 0x6c,
|
||||
0x73, 0x50, 0x72, 0x65, 0x66, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x48, 0x00, 0x52, 0x09, 0x70, 0x72,
|
||||
0x65, 0x66, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x12, 0x48, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69,
|
||||
0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x63, 0x6b,
|
||||
0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x12, 0x5c, 0x0a, 0x0e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x71, 0x75, 0x69, 0x6c,
|
||||
0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x64, 0x61, 0x74, 0x61,
|
||||
0x2e, 0x70, 0x62, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x41,
|
||||
0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52,
|
||||
0x0e, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42,
|
||||
0x0e, 0x0a, 0x0c, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22,
|
||||
0xce, 0x01, 0x0a, 0x21, 0x44, 0x61, 0x74, 0x61, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73,
|
||||
0x65, 0x64, 0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x65,
|
||||
0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x4e, 0x0a, 0x09, 0x70, 0x72, 0x65, 0x66, 0x6c, 0x69, 0x67,
|
||||
0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69,
|
||||
0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x63, 0x6b,
|
||||
0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x50,
|
||||
0x72, 0x65, 0x66, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x48, 0x00, 0x52, 0x09, 0x70, 0x72, 0x65, 0x66,
|
||||
0x6c, 0x69, 0x67, 0x68, 0x74, 0x12, 0x49, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62,
|
||||
0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70,
|
||||
0x62, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64,
|
||||
0x53, 0x79, 0x6e, 0x63, 0x48, 0x00, 0x52, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x42, 0x0e, 0x0a, 0x0c, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
|
||||
0x22, 0xa1, 0x01, 0x0a, 0x12, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x72,
|
||||
0x6f, 0x6f, 0x66, 0x73, 0x4d, 0x61, 0x70, 0x12, 0x21, 0x0a, 0x0c, 0x66, 0x72, 0x61, 0x6d, 0x65,
|
||||
0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x66,
|
||||
0x72, 0x61, 0x6d, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x72,
|
||||
0x6f, 0x6f, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x70, 0x72, 0x6f, 0x6f, 0x66,
|
||||
0x12, 0x52, 0x0a, 0x0b, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18,
|
||||
0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69,
|
||||
0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x62, 0x2e,
|
||||
0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d,
|
||||
0x65, 0x6e, 0x74, 0x73, 0x4d, 0x61, 0x70, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d,
|
||||
0x65, 0x6e, 0x74, 0x73, 0x22, 0x3e, 0x0a, 0x14, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f,
|
||||
0x6e, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x4d, 0x61, 0x70, 0x12, 0x12, 0x0a, 0x04,
|
||||
0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68,
|
||||
0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04,
|
||||
0x64, 0x61, 0x74, 0x61, 0x22, 0x7b, 0x0a, 0x17, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x6f,
|
||||
0x6e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x4d, 0x61, 0x70, 0x12,
|
||||
0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x0c, 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x12,
|
||||
0x19, 0x0a, 0x08, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x07, 0x74, 0x79, 0x70, 0x65, 0x55, 0x72, 0x6c, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x65,
|
||||
0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03,
|
||||
0x28, 0x0c, 0x52, 0x0d, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x48, 0x61, 0x73, 0x68, 0x65,
|
||||
0x73, 0x22, 0x51, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x44, 0x61, 0x74, 0x61, 0x46, 0x72, 0x61, 0x6d,
|
||||
0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x66, 0x72, 0x61, 0x6d,
|
||||
0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b,
|
||||
0x66, 0x72, 0x61, 0x6d, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x70,
|
||||
0x65, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x65,
|
||||
0x65, 0x72, 0x49, 0x64, 0x22, 0x70, 0x0a, 0x11, 0x44, 0x61, 0x74, 0x61, 0x46, 0x72, 0x61, 0x6d,
|
||||
0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x0b, 0x63, 0x6c, 0x6f,
|
||||
0x63, 0x6b, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24,
|
||||
0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65,
|
||||
0x2e, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x46,
|
||||
0x72, 0x61, 0x6d, 0x65, 0x52, 0x0a, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x72, 0x61, 0x6d, 0x65,
|
||||
0x12, 0x14, 0x0a, 0x05, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52,
|
||||
0x05, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x22, 0x51, 0x0a, 0x17, 0x50, 0x72, 0x65, 0x4d, 0x69, 0x64,
|
||||
0x6e, 0x69, 0x67, 0x68, 0x74, 0x4d, 0x69, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x0c, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x69,
|
||||
0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09,
|
||||
0x69, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x34, 0x0a, 0x1c, 0x50, 0x72, 0x65,
|
||||
0x4d, 0x69, 0x64, 0x6e, 0x69, 0x67, 0x68, 0x74, 0x4d, 0x69, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74,
|
||||
0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6f, 0x77, 0x6e,
|
||||
0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x22,
|
||||
0x97, 0x01, 0x0a, 0x10, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x62, 0x72, 0x6f, 0x61, 0x64,
|
||||
0x63, 0x61, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x04, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x74, 0x6f, 0x12, 0x47, 0x0a, 0x0c, 0x63, 0x6c, 0x6f, 0x63,
|
||||
0x6b, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24,
|
||||
0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65,
|
||||
0x2e, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x46,
|
||||
0x72, 0x61, 0x6d, 0x65, 0x52, 0x0b, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x72, 0x61, 0x6d, 0x65,
|
||||
0x73, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28,
|
||||
0x0c, 0x52, 0x06, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x22, 0xe6, 0x01, 0x0a, 0x15, 0x43, 0x68,
|
||||
0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x70, 0x65, 0x65, 0x72, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04,
|
||||
0x63, 0x6f, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x63, 0x6f, 0x72, 0x65,
|
||||
0x12, 0x45, 0x0a, 0x0b, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x18,
|
||||
0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69,
|
||||
0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x70, 0x62,
|
||||
0x2e, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x52, 0x0a, 0x63, 0x6c, 0x6f,
|
||||
0x63, 0x6b, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75,
|
||||
0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12,
|
||||
0x21, 0x0a, 0x0c, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18,
|
||||
0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x4e, 0x75, 0x6d, 0x62,
|
||||
0x65, 0x72, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x69, 0x66, 0x66, 0x69, 0x63, 0x75, 0x6c, 0x74, 0x79,
|
||||
0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x64, 0x69, 0x66, 0x66, 0x69, 0x63, 0x75, 0x6c,
|
||||
0x74, 0x79, 0x22, 0x30, 0x0a, 0x16, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x50,
|
||||
0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06,
|
||||
0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6f, 0x75,
|
||||
0x74, 0x70, 0x75, 0x74, 0x32, 0xff, 0x05, 0x0a, 0x0b, 0x44, 0x61, 0x74, 0x61, 0x53, 0x65, 0x72,
|
||||
0x76, 0x69, 0x63, 0x65, 0x12, 0x76, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x72,
|
||||
0x65, 0x73, 0x73, 0x65, 0x64, 0x53, 0x79, 0x6e, 0x63, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12,
|
||||
0x2c, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64,
|
||||
0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6c, 0x6f, 0x63, 0x6b,
|
||||
0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e,
|
||||
0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e,
|
||||
0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x62, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x43, 0x6f, 0x6d, 0x70,
|
||||
0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x53, 0x79, 0x6e, 0x63, 0x30, 0x01, 0x12, 0x9a, 0x01, 0x0a,
|
||||
0x1d, 0x4e, 0x65, 0x67, 0x6f, 0x74, 0x69, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65,
|
||||
0x73, 0x73, 0x65, 0x64, 0x53, 0x79, 0x6e, 0x63, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x39,
|
||||
0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65,
|
||||
0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x62, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x43, 0x6f, 0x6d,
|
||||
0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x3a, 0x2e, 0x71, 0x75, 0x69, 0x6c,
|
||||
0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x64, 0x61, 0x74, 0x61,
|
||||
0x2e, 0x70, 0x62, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73,
|
||||
0x65, 0x64, 0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x73,
|
||||
0x73, 0x61, 0x67, 0x65, 0x1a, 0x3a, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75,
|
||||
0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x62, 0x2e, 0x44,
|
||||
0x61, 0x74, 0x61, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x53, 0x79, 0x6e,
|
||||
0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
|
||||
0x28, 0x01, 0x30, 0x01, 0x12, 0x76, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69,
|
||||
0x63, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x2e, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69,
|
||||
0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x63, 0x68, 0x61, 0x6e, 0x6e,
|
||||
0x65, 0x6c, 0x2e, 0x70, 0x62, 0x2e, 0x50, 0x32, 0x50, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c,
|
||||
0x45, 0x6e, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x1a, 0x2e, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69,
|
||||
0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x63, 0x68, 0x61, 0x6e, 0x6e,
|
||||
0x65, 0x6c, 0x2e, 0x70, 0x62, 0x2e, 0x50, 0x32, 0x50, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c,
|
||||
0x45, 0x6e, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x28, 0x01, 0x30, 0x01, 0x12, 0x68, 0x0a, 0x0c,
|
||||
0x47, 0x65, 0x74, 0x44, 0x61, 0x74, 0x61, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x12, 0x2c, 0x2e, 0x71,
|
||||
0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x64,
|
||||
0x61, 0x74, 0x61, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x61, 0x74, 0x61, 0x46, 0x72,
|
||||
0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x71, 0x75, 0x69,
|
||||
0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x64, 0x61, 0x74,
|
||||
0x61, 0x2e, 0x70, 0x62, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x73, 0x0a, 0x15, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65,
|
||||
0x50, 0x72, 0x65, 0x4d, 0x69, 0x64, 0x6e, 0x69, 0x67, 0x68, 0x74, 0x4d, 0x69, 0x6e, 0x74, 0x12,
|
||||
0x28, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64,
|
||||
0x65, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x4d, 0x69, 0x6e, 0x74, 0x43, 0x6f,
|
||||
0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x71, 0x75, 0x69, 0x6c,
|
||||
0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x64, 0x61, 0x74, 0x61,
|
||||
0x2e, 0x70, 0x62, 0x2e, 0x50, 0x72, 0x65, 0x4d, 0x69, 0x64, 0x6e, 0x69, 0x67, 0x68, 0x74, 0x4d,
|
||||
0x69, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x83, 0x01, 0x0a, 0x18,
|
||||
0x47, 0x65, 0x74, 0x50, 0x72, 0x65, 0x4d, 0x69, 0x64, 0x6e, 0x69, 0x67, 0x68, 0x74, 0x4d, 0x69,
|
||||
0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x35, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69,
|
||||
0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e,
|
||||
0x70, 0x62, 0x2e, 0x50, 0x72, 0x65, 0x4d, 0x69, 0x64, 0x6e, 0x69, 0x67, 0x68, 0x74, 0x4d, 0x69,
|
||||
0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
0x30, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64,
|
||||
0x65, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x62, 0x2e, 0x50, 0x72, 0x65, 0x4d, 0x69, 0x64,
|
||||
0x6e, 0x69, 0x67, 0x68, 0x74, 0x4d, 0x69, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x32, 0x8c, 0x01, 0x0a, 0x0e, 0x44, 0x61, 0x74, 0x61, 0x49, 0x50, 0x43, 0x53, 0x65, 0x72,
|
||||
0x76, 0x69, 0x63, 0x65, 0x12, 0x7a, 0x0a, 0x17, 0x43, 0x61, 0x6c, 0x63, 0x75, 0x6c, 0x61, 0x74,
|
||||
0x65, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12,
|
||||
0x2e, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64,
|
||||
0x65, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65,
|
||||
0x6e, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
0x2f, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64,
|
||||
0x65, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65,
|
||||
0x6e, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x42, 0x3a, 0x5a, 0x38, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69,
|
||||
0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62,
|
||||
0x72, 0x69, 0x75, 0x6d, 0x2f, 0x6d, 0x6f, 0x6e, 0x6f, 0x72, 0x65, 0x70, 0x6f, 0x2f, 0x6e, 0x6f,
|
||||
0x64, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x73, 0x62, 0x06, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x33,
|
||||
0x65, 0x64, 0x53, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x65,
|
||||
0x73, 0x73, 0x61, 0x67, 0x65, 0x28, 0x01, 0x30, 0x01, 0x12, 0x76, 0x0a, 0x10, 0x47, 0x65, 0x74,
|
||||
0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x2e, 0x2e,
|
||||
0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e,
|
||||
0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x2e, 0x70, 0x62, 0x2e, 0x50, 0x32, 0x50, 0x43, 0x68,
|
||||
0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x45, 0x6e, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x1a, 0x2e, 0x2e,
|
||||
0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e,
|
||||
0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x2e, 0x70, 0x62, 0x2e, 0x50, 0x32, 0x50, 0x43, 0x68,
|
||||
0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x45, 0x6e, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x28, 0x01, 0x30,
|
||||
0x01, 0x12, 0x68, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x44, 0x61, 0x74, 0x61, 0x46, 0x72, 0x61, 0x6d,
|
||||
0x65, 0x12, 0x2c, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e,
|
||||
0x6f, 0x64, 0x65, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x44,
|
||||
0x61, 0x74, 0x61, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
0x2a, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64,
|
||||
0x65, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x62, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x46, 0x72,
|
||||
0x61, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x73, 0x0a, 0x15, 0x48,
|
||||
0x61, 0x6e, 0x64, 0x6c, 0x65, 0x50, 0x72, 0x65, 0x4d, 0x69, 0x64, 0x6e, 0x69, 0x67, 0x68, 0x74,
|
||||
0x4d, 0x69, 0x6e, 0x74, 0x12, 0x28, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75,
|
||||
0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x4d,
|
||||
0x69, 0x6e, 0x74, 0x43, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30,
|
||||
0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65,
|
||||
0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x62, 0x2e, 0x50, 0x72, 0x65, 0x4d, 0x69, 0x64, 0x6e,
|
||||
0x69, 0x67, 0x68, 0x74, 0x4d, 0x69, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x12, 0x83, 0x01, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x50, 0x72, 0x65, 0x4d, 0x69, 0x64, 0x6e, 0x69,
|
||||
0x67, 0x68, 0x74, 0x4d, 0x69, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x35, 0x2e,
|
||||
0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e,
|
||||
0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x62, 0x2e, 0x50, 0x72, 0x65, 0x4d, 0x69, 0x64, 0x6e, 0x69,
|
||||
0x67, 0x68, 0x74, 0x4d, 0x69, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75,
|
||||
0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x62, 0x2e, 0x50,
|
||||
0x72, 0x65, 0x4d, 0x69, 0x64, 0x6e, 0x69, 0x67, 0x68, 0x74, 0x4d, 0x69, 0x6e, 0x74, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x8c, 0x01, 0x0a, 0x0e, 0x44, 0x61, 0x74, 0x61, 0x49,
|
||||
0x50, 0x43, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x7a, 0x0a, 0x17, 0x43, 0x61, 0x6c,
|
||||
0x63, 0x75, 0x6c, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x50,
|
||||
0x72, 0x6f, 0x6f, 0x66, 0x12, 0x2e, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75,
|
||||
0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x62, 0x2e, 0x43,
|
||||
0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75,
|
||||
0x6d, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x62, 0x2e, 0x43,
|
||||
0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x3a, 0x5a, 0x38, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e,
|
||||
0x71, 0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x71,
|
||||
0x75, 0x69, 0x6c, 0x69, 0x62, 0x72, 0x69, 0x75, 0x6d, 0x2f, 0x6d, 0x6f, 0x6e, 0x6f, 0x72, 0x65,
|
||||
0x70, 0x6f, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
|
||||
0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
||||
@ -26,6 +26,7 @@ message DataPeer {
|
||||
reserved 7;
|
||||
reserved "public_key";
|
||||
bytes total_distance = 8;
|
||||
bytes patch_version = 9;
|
||||
}
|
||||
|
||||
message DataCompressedSync {
|
||||
|
||||
@ -182,6 +182,11 @@ func (s *Ed448Signature) Verify(msg []byte) error {
|
||||
return errors.Wrap(errors.New("invalid length for signature"), "verify")
|
||||
}
|
||||
|
||||
return s.verifyUnsafe(msg)
|
||||
}
|
||||
|
||||
// verifyUnsafe is used to verify a signature without checking the length of the public key and signature.
|
||||
func (s *Ed448Signature) verifyUnsafe(msg []byte) error {
|
||||
if !ed448.Verify(s.PublicKey.KeyValue, msg, s.Signature, "") {
|
||||
return errors.Wrap(errors.New("invalid signature for public key"), "verify")
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ package protobufs
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"time"
|
||||
|
||||
"github.com/iden3/go-iden3-crypto/poseidon"
|
||||
pcrypto "github.com/libp2p/go-libp2p/core/crypto"
|
||||
@ -22,14 +23,6 @@ func (t *TokenRequest) Priority() uint64 {
|
||||
func (t *MintCoinRequest) RingAndParallelism(
|
||||
ringCalc func(addr []byte) int,
|
||||
) (int, uint32, error) {
|
||||
payload := []byte("mint")
|
||||
for _, p := range t.Proofs {
|
||||
payload = append(payload, p...)
|
||||
}
|
||||
if err := t.Signature.Verify(payload); err != nil {
|
||||
return -1, 0, errors.New("invalid")
|
||||
}
|
||||
|
||||
pk, err := pcrypto.UnmarshalEd448PublicKey(
|
||||
t.Signature.PublicKey.KeyValue,
|
||||
)
|
||||
@ -58,3 +51,93 @@ func (t *MintCoinRequest) RingAndParallelism(
|
||||
|
||||
return -1, 0, errors.New("invalid")
|
||||
}
|
||||
|
||||
// TokenRequest returns the TokenRequest for the TransferCoinRequest.
|
||||
func (t *TransferCoinRequest) TokenRequest() *TokenRequest {
|
||||
return &TokenRequest{
|
||||
Request: &TokenRequest_Transfer{
|
||||
Transfer: t,
|
||||
},
|
||||
Timestamp: time.Now().UnixMilli(),
|
||||
}
|
||||
}
|
||||
|
||||
// TokenRequest returns the TokenRequest for the SplitCoinRequest.
|
||||
func (t *SplitCoinRequest) TokenRequest() *TokenRequest {
|
||||
return &TokenRequest{
|
||||
Request: &TokenRequest_Split{
|
||||
Split: t,
|
||||
},
|
||||
Timestamp: time.Now().UnixMilli(),
|
||||
}
|
||||
}
|
||||
|
||||
// TokenRequest returns the TokenRequest for the MergeCoinRequest.
|
||||
func (t *MergeCoinRequest) TokenRequest() *TokenRequest {
|
||||
return &TokenRequest{
|
||||
Request: &TokenRequest_Merge{
|
||||
Merge: t,
|
||||
},
|
||||
Timestamp: time.Now().UnixMilli(),
|
||||
}
|
||||
}
|
||||
|
||||
// TokenRequest returns the TokenRequest for the MintCoinRequest.
|
||||
func (t *MintCoinRequest) TokenRequest() *TokenRequest {
|
||||
return &TokenRequest{
|
||||
Request: &TokenRequest_Mint{
|
||||
Mint: t,
|
||||
},
|
||||
Timestamp: time.Now().UnixMilli(),
|
||||
}
|
||||
}
|
||||
|
||||
// TokenRequest returns the TokenRequest for the AnnounceProverRequest.
|
||||
func (t *AnnounceProverRequest) TokenRequest() *TokenRequest {
|
||||
return &TokenRequest{
|
||||
Request: &TokenRequest_Announce{
|
||||
Announce: t,
|
||||
},
|
||||
Timestamp: time.Now().UnixMilli(),
|
||||
}
|
||||
}
|
||||
|
||||
// TokenRequest returns the TokenRequest for the AnnounceProverJoin.
|
||||
func (t *AnnounceProverJoin) TokenRequest() *TokenRequest {
|
||||
return &TokenRequest{
|
||||
Request: &TokenRequest_Join{
|
||||
Join: t,
|
||||
},
|
||||
Timestamp: time.Now().UnixMilli(),
|
||||
}
|
||||
}
|
||||
|
||||
// TokenRequest returns the TokenRequest for the AnnounceProverLeave.
|
||||
func (t *AnnounceProverLeave) TokenRequest() *TokenRequest {
|
||||
return &TokenRequest{
|
||||
Request: &TokenRequest_Leave{
|
||||
Leave: t,
|
||||
},
|
||||
Timestamp: time.Now().UnixMilli(),
|
||||
}
|
||||
}
|
||||
|
||||
// TokenRequest returns the TokenRequest for the AnnounceProverPause.
|
||||
func (t *AnnounceProverPause) TokenRequest() *TokenRequest {
|
||||
return &TokenRequest{
|
||||
Request: &TokenRequest_Pause{
|
||||
Pause: t,
|
||||
},
|
||||
Timestamp: time.Now().UnixMilli(),
|
||||
}
|
||||
}
|
||||
|
||||
// TokenRequest returns the TokenRequest for the AnnounceProverResume.
|
||||
func (t *AnnounceProverResume) TokenRequest() *TokenRequest {
|
||||
return &TokenRequest{
|
||||
Request: &TokenRequest_Resume{
|
||||
Resume: t,
|
||||
},
|
||||
Timestamp: time.Now().UnixMilli(),
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -43,6 +43,7 @@ message PeerInfo {
|
||||
bytes signature = 6;
|
||||
bytes public_key = 7;
|
||||
bytes total_distance = 8;
|
||||
bytes patch_version = 9;
|
||||
}
|
||||
|
||||
message PeerInfoResponse {
|
||||
|
||||
700
node/protobufs/validation.go
Normal file
700
node/protobufs/validation.go
Normal file
@ -0,0 +1,700 @@
|
||||
package protobufs
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type signatureMessage interface {
|
||||
signatureMessage() []byte
|
||||
}
|
||||
|
||||
var _ signatureMessage = (*TransferCoinRequest)(nil)
|
||||
|
||||
func (t *TransferCoinRequest) signatureMessage() []byte {
|
||||
payload := []byte("transfer")
|
||||
payload = append(payload, t.OfCoin.Address...)
|
||||
payload = append(
|
||||
payload,
|
||||
t.ToAccount.GetImplicitAccount().Address...,
|
||||
)
|
||||
return payload
|
||||
}
|
||||
|
||||
var _ signatureMessage = (*SplitCoinRequest)(nil)
|
||||
|
||||
func (t *SplitCoinRequest) signatureMessage() []byte {
|
||||
payload := []byte("split")
|
||||
payload = append(payload, t.OfCoin.Address...)
|
||||
for _, a := range t.Amounts {
|
||||
payload = append(payload, a...)
|
||||
}
|
||||
return payload
|
||||
}
|
||||
|
||||
var _ signatureMessage = (*MergeCoinRequest)(nil)
|
||||
|
||||
func (t *MergeCoinRequest) signatureMessage() []byte {
|
||||
payload := []byte("merge")
|
||||
for _, c := range t.Coins {
|
||||
payload = append(payload, c.Address...)
|
||||
}
|
||||
return payload
|
||||
}
|
||||
|
||||
var _ signatureMessage = (*MintCoinRequest)(nil)
|
||||
|
||||
func (t *MintCoinRequest) signatureMessage() []byte {
|
||||
payload := []byte("mint")
|
||||
for _, p := range t.Proofs {
|
||||
payload = append(payload, p...)
|
||||
}
|
||||
return payload
|
||||
}
|
||||
|
||||
// NOTE: AnnounceProverRequest has a non-trivial signature payload.
|
||||
|
||||
var _ signatureMessage = (*AnnounceProverJoin)(nil)
|
||||
|
||||
func (t *AnnounceProverJoin) signatureMessage() []byte {
|
||||
payload := []byte("join")
|
||||
payload = binary.BigEndian.AppendUint64(payload, t.FrameNumber)
|
||||
payload = append(payload, t.Filter...)
|
||||
return payload
|
||||
}
|
||||
|
||||
var _ signatureMessage = (*AnnounceProverLeave)(nil)
|
||||
|
||||
func (t *AnnounceProverLeave) signatureMessage() []byte {
|
||||
payload := []byte("leave")
|
||||
payload = binary.BigEndian.AppendUint64(payload, t.FrameNumber)
|
||||
payload = append(payload, t.Filter...)
|
||||
return payload
|
||||
}
|
||||
|
||||
var _ signatureMessage = (*AnnounceProverPause)(nil)
|
||||
|
||||
func (t *AnnounceProverPause) signatureMessage() []byte {
|
||||
payload := []byte("pause")
|
||||
payload = binary.BigEndian.AppendUint64(payload, t.FrameNumber)
|
||||
payload = append(payload, t.Filter...)
|
||||
return payload
|
||||
}
|
||||
|
||||
var _ signatureMessage = (*AnnounceProverResume)(nil)
|
||||
|
||||
func (t *AnnounceProverResume) signatureMessage() []byte {
|
||||
payload := []byte("resume")
|
||||
payload = binary.BigEndian.AppendUint64(payload, t.FrameNumber)
|
||||
payload = append(payload, t.Filter...)
|
||||
return payload
|
||||
}
|
||||
|
||||
// SignedMessage is a message that has a signature.
|
||||
type SignedMessage interface {
|
||||
// ValidateSignature checks the signature of the message.
|
||||
// The message contents are expected to be valid - validation
|
||||
// of contents must precede validation of the signature.
|
||||
ValidateSignature() error
|
||||
}
|
||||
|
||||
var _ SignedMessage = (*TransferCoinRequest)(nil)
|
||||
|
||||
// ValidateSignature checks the signature of the transfer coin request.
|
||||
func (t *TransferCoinRequest) ValidateSignature() error {
|
||||
if err := t.Signature.verifyUnsafe(t.signatureMessage()); err != nil {
|
||||
return errors.Wrap(err, "validate signature")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ SignedMessage = (*SplitCoinRequest)(nil)
|
||||
|
||||
// ValidateSignature checks the signature of the split coin request.
|
||||
func (t *SplitCoinRequest) ValidateSignature() error {
|
||||
if err := t.Signature.verifyUnsafe(t.signatureMessage()); err != nil {
|
||||
return errors.Wrap(err, "validate signature")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ SignedMessage = (*MergeCoinRequest)(nil)
|
||||
|
||||
// ValidateSignature checks the signature of the merge coin request.
|
||||
func (t *MergeCoinRequest) ValidateSignature() error {
|
||||
if err := t.Signature.verifyUnsafe(t.signatureMessage()); err != nil {
|
||||
return errors.Wrap(err, "validate signature")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ SignedMessage = (*MintCoinRequest)(nil)
|
||||
|
||||
// ValidateSignature checks the signature of the mint coin request.
|
||||
func (t *MintCoinRequest) ValidateSignature() error {
|
||||
if err := t.Signature.verifyUnsafe(t.signatureMessage()); err != nil {
|
||||
return errors.Wrap(err, "validate signature")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ SignedMessage = (*AnnounceProverRequest)(nil)
|
||||
|
||||
// ValidateSignature checks the signature of the announce prover request.
|
||||
func (t *AnnounceProverRequest) ValidateSignature() error {
|
||||
payload := []byte{}
|
||||
primary := t.PublicKeySignaturesEd448[0]
|
||||
for _, p := range t.PublicKeySignaturesEd448[1:] {
|
||||
payload = append(payload, p.PublicKey.KeyValue...)
|
||||
if err := p.verifyUnsafe(primary.PublicKey.KeyValue); err != nil {
|
||||
return errors.Wrap(err, "validate signature")
|
||||
}
|
||||
}
|
||||
if err := primary.verifyUnsafe(payload); err != nil {
|
||||
return errors.Wrap(err, "validate signature")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ SignedMessage = (*AnnounceProverJoin)(nil)
|
||||
|
||||
// ValidateSignature checks the signature of the announce prover join.
|
||||
func (t *AnnounceProverJoin) ValidateSignature() error {
|
||||
if err := t.PublicKeySignatureEd448.verifyUnsafe(t.signatureMessage()); err != nil {
|
||||
return errors.Wrap(err, "validate signature")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ SignedMessage = (*AnnounceProverLeave)(nil)
|
||||
|
||||
// ValidateSignature checks the signature of the announce prover leave.
|
||||
func (t *AnnounceProverLeave) ValidateSignature() error {
|
||||
if err := t.PublicKeySignatureEd448.verifyUnsafe(t.signatureMessage()); err != nil {
|
||||
return errors.Wrap(err, "validate signature")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ SignedMessage = (*AnnounceProverPause)(nil)
|
||||
|
||||
// ValidateSignature checks the signature of the announce prover pause.
|
||||
func (t *AnnounceProverPause) ValidateSignature() error {
|
||||
if err := t.PublicKeySignatureEd448.verifyUnsafe(t.signatureMessage()); err != nil {
|
||||
return errors.Wrap(err, "validate signature")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ SignedMessage = (*AnnounceProverResume)(nil)
|
||||
|
||||
// ValidateSignature checks the signature of the announce prover resume.
|
||||
func (t *AnnounceProverResume) ValidateSignature() error {
|
||||
if err := t.PublicKeySignatureEd448.verifyUnsafe(t.signatureMessage()); err != nil {
|
||||
return errors.Wrap(err, "validate signature")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ValidatableMessage is a message that can be validated.
|
||||
type ValidatableMessage interface {
|
||||
// Validate checks the message contents.
|
||||
// It will also verify signatures if the message is signed.
|
||||
Validate() error
|
||||
}
|
||||
|
||||
var _ ValidatableMessage = (*Ed448PublicKey)(nil)
|
||||
|
||||
// Validate checks the Ed448 public key.
|
||||
func (e *Ed448PublicKey) Validate() error {
|
||||
if e == nil {
|
||||
return errors.New("nil Ed448 public key")
|
||||
}
|
||||
if len(e.KeyValue) != 57 {
|
||||
return errors.New("invalid Ed448 public key")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ ValidatableMessage = (*Ed448Signature)(nil)
|
||||
|
||||
// Validate checks the Ed448 signature.
|
||||
func (e *Ed448Signature) Validate() error {
|
||||
if e == nil {
|
||||
return errors.New("nil Ed448 signature")
|
||||
}
|
||||
if err := e.PublicKey.Validate(); err != nil {
|
||||
return errors.Wrap(err, "public key")
|
||||
}
|
||||
if len(e.Signature) != 114 {
|
||||
return errors.New("invalid Ed448 signature")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ ValidatableMessage = (*ImplicitAccount)(nil)
|
||||
|
||||
// Validate checks the implicit account.
|
||||
func (i *ImplicitAccount) Validate() error {
|
||||
if i == nil {
|
||||
return errors.New("nil implicit account")
|
||||
}
|
||||
// TODO: Validate ImplicitType.
|
||||
if len(i.Address) != 32 {
|
||||
return errors.New("invalid implicit account")
|
||||
}
|
||||
// TODO: Validate Domain.
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ ValidatableMessage = (*OriginatedAccountRef)(nil)
|
||||
|
||||
// Validate checks the originated account.
|
||||
func (o *OriginatedAccountRef) Validate() error {
|
||||
if o == nil {
|
||||
return errors.New("nil originated account")
|
||||
}
|
||||
if len(o.Address) != 32 {
|
||||
return errors.New("invalid originated account")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ ValidatableMessage = (*AccountRef)(nil)
|
||||
|
||||
// Validate checks the account reference.
|
||||
func (a *AccountRef) Validate() error {
|
||||
if a == nil {
|
||||
return errors.New("nil account reference")
|
||||
}
|
||||
switch {
|
||||
case a.GetImplicitAccount() != nil:
|
||||
if err := a.GetImplicitAccount().Validate(); err != nil {
|
||||
return errors.Wrap(err, "implicit account")
|
||||
}
|
||||
case a.GetOriginatedAccount() != nil:
|
||||
if err := a.GetOriginatedAccount().Validate(); err != nil {
|
||||
return errors.Wrap(err, "originated account")
|
||||
}
|
||||
default:
|
||||
return errors.New("invalid account reference")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ ValidatableMessage = (*CoinRef)(nil)
|
||||
|
||||
// Validate checks the coin reference.
|
||||
func (c *CoinRef) Validate() error {
|
||||
if c == nil {
|
||||
return errors.New("nil coin reference")
|
||||
}
|
||||
if len(c.Address) != 32 {
|
||||
return errors.New("invalid coin reference")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ ValidatableMessage = (*AccountAllowanceRef)(nil)
|
||||
|
||||
// Validate checks the account allowance reference.
|
||||
func (a *AccountAllowanceRef) Validate() error {
|
||||
if a == nil {
|
||||
return errors.New("nil account allowance reference")
|
||||
}
|
||||
if len(a.Address) != 32 {
|
||||
return errors.New("invalid account allowance reference")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ ValidatableMessage = (*CoinAllowanceRef)(nil)
|
||||
|
||||
// Validate checks the coin allowance reference.
|
||||
func (c *CoinAllowanceRef) Validate() error {
|
||||
if c == nil {
|
||||
return errors.New("nil coin allowance reference")
|
||||
}
|
||||
if len(c.Address) != 32 {
|
||||
return errors.New("invalid coin allowance reference")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ ValidatableMessage = (*TokenRequest)(nil)
|
||||
|
||||
// Validate checks the token request.
|
||||
func (t *TokenRequest) Validate() error {
|
||||
if t == nil {
|
||||
return errors.New("nil token request")
|
||||
}
|
||||
switch {
|
||||
case t.GetTransfer() != nil:
|
||||
return t.GetTransfer().Validate()
|
||||
case t.GetSplit() != nil:
|
||||
return t.GetSplit().Validate()
|
||||
case t.GetMerge() != nil:
|
||||
return t.GetMerge().Validate()
|
||||
case t.GetMint() != nil:
|
||||
return t.GetMint().Validate()
|
||||
case t.GetAnnounce() != nil:
|
||||
return t.GetAnnounce().Validate()
|
||||
case t.GetJoin() != nil:
|
||||
return t.GetJoin().Validate()
|
||||
case t.GetLeave() != nil:
|
||||
return t.GetLeave().Validate()
|
||||
case t.GetPause() != nil:
|
||||
return t.GetPause().Validate()
|
||||
case t.GetResume() != nil:
|
||||
return t.GetResume().Validate()
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
var _ ValidatableMessage = (*TransferCoinRequest)(nil)
|
||||
|
||||
// Validate checks the transfer coin request.
|
||||
func (t *TransferCoinRequest) Validate() error {
|
||||
if t == nil {
|
||||
return errors.New("nil transfer coin request")
|
||||
}
|
||||
if err := t.ToAccount.Validate(); err != nil {
|
||||
return errors.Wrap(err, "to account")
|
||||
}
|
||||
// TODO: Validate RefundAccount.
|
||||
if err := t.OfCoin.Validate(); err != nil {
|
||||
return errors.Wrap(err, "of coin")
|
||||
}
|
||||
// TODO: Validate Expiry.
|
||||
// TODO: Validate AccountAllowance.
|
||||
// TODO: Validate CoinAllowance.
|
||||
if err := t.Signature.Validate(); err != nil {
|
||||
return errors.Wrap(err, "signature")
|
||||
}
|
||||
if err := t.ValidateSignature(); err != nil {
|
||||
return errors.Wrap(err, "signature")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ ValidatableMessage = (*SplitCoinRequest)(nil)
|
||||
|
||||
// Validate checks the split coin request.
|
||||
func (t *SplitCoinRequest) Validate() error {
|
||||
if t == nil {
|
||||
return errors.New("nil split coin request")
|
||||
}
|
||||
if err := t.OfCoin.Validate(); err != nil {
|
||||
return errors.Wrap(err, "of coin")
|
||||
}
|
||||
if n := len(t.Amounts); n == 0 || n > 100 {
|
||||
return errors.New("invalid amounts")
|
||||
}
|
||||
for _, a := range t.Amounts {
|
||||
if n := len(a); n == 0 || n > 32 {
|
||||
return errors.New("invalid amount")
|
||||
}
|
||||
}
|
||||
// TODO: Validate AccountAllowance.
|
||||
// TODO: Validate CoinAllowance.
|
||||
if err := t.Signature.Validate(); err != nil {
|
||||
return errors.Wrap(err, "signature")
|
||||
}
|
||||
if err := t.ValidateSignature(); err != nil {
|
||||
return errors.Wrap(err, "signature")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ ValidatableMessage = (*MergeCoinRequest)(nil)
|
||||
|
||||
// Validate checks the merge coin request.
|
||||
func (t *MergeCoinRequest) Validate() error {
|
||||
if t == nil {
|
||||
return errors.New("nil merge coin request")
|
||||
}
|
||||
if len(t.Coins) == 0 {
|
||||
return errors.New("invalid coins")
|
||||
}
|
||||
for _, c := range t.Coins {
|
||||
if err := c.Validate(); err != nil {
|
||||
return errors.Wrap(err, "coin")
|
||||
}
|
||||
}
|
||||
// TODO: Validate AccountAllowance.
|
||||
// TODO: Validate CoinAllowance.
|
||||
if err := t.Signature.Validate(); err != nil {
|
||||
return errors.Wrap(err, "signature")
|
||||
}
|
||||
if err := t.ValidateSignature(); err != nil {
|
||||
return errors.Wrap(err, "signature")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ ValidatableMessage = (*MintCoinRequest)(nil)
|
||||
|
||||
// Validate checks the mint coin request.
|
||||
func (t *MintCoinRequest) Validate() error {
|
||||
if t == nil {
|
||||
return errors.New("nil mint coin request")
|
||||
}
|
||||
if len(t.Proofs) == 0 {
|
||||
return errors.New("invalid proofs")
|
||||
}
|
||||
// TODO: Validate AccountAllowance.
|
||||
if err := t.Signature.Validate(); err != nil {
|
||||
return errors.Wrap(err, "signature")
|
||||
}
|
||||
if err := t.ValidateSignature(); err != nil {
|
||||
return errors.Wrap(err, "signature")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ ValidatableMessage = (*AnnounceProverRequest)(nil)
|
||||
|
||||
// Validate checks the announce prover request.
|
||||
func (t *AnnounceProverRequest) Validate() error {
|
||||
if t == nil {
|
||||
return errors.New("nil announce prover request")
|
||||
}
|
||||
if len(t.PublicKeySignaturesEd448) == 0 {
|
||||
return errors.New("invalid public key signatures")
|
||||
}
|
||||
for _, p := range t.PublicKeySignaturesEd448 {
|
||||
if err := p.Validate(); err != nil {
|
||||
return errors.Wrap(err, "public key signature")
|
||||
}
|
||||
}
|
||||
if err := t.ValidateSignature(); err != nil {
|
||||
return errors.Wrap(err, "signature")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ ValidatableMessage = (*AnnounceProverJoin)(nil)
|
||||
|
||||
// Validate checks the announce prover join.
|
||||
func (t *AnnounceProverJoin) Validate() error {
|
||||
if t == nil {
|
||||
return errors.New("nil announce prover join")
|
||||
}
|
||||
if len(t.Filter) != 32 {
|
||||
return errors.New("invalid filter")
|
||||
}
|
||||
if announce := t.Announce; announce != nil {
|
||||
if err := announce.Validate(); err != nil {
|
||||
return errors.Wrap(err, "announce")
|
||||
}
|
||||
}
|
||||
if err := t.PublicKeySignatureEd448.Validate(); err != nil {
|
||||
return errors.Wrap(err, "public key signature")
|
||||
}
|
||||
if err := t.ValidateSignature(); err != nil {
|
||||
return errors.Wrap(err, "signature")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ ValidatableMessage = (*AnnounceProverLeave)(nil)
|
||||
|
||||
// Validate checks the announce prover leave.
|
||||
func (t *AnnounceProverLeave) Validate() error {
|
||||
if t == nil {
|
||||
return errors.New("nil announce prover leave")
|
||||
}
|
||||
if len(t.Filter) != 32 {
|
||||
return errors.New("invalid filter")
|
||||
}
|
||||
if err := t.PublicKeySignatureEd448.Validate(); err != nil {
|
||||
return errors.Wrap(err, "public key signature")
|
||||
}
|
||||
if err := t.ValidateSignature(); err != nil {
|
||||
return errors.Wrap(err, "signature")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ ValidatableMessage = (*AnnounceProverPause)(nil)
|
||||
|
||||
// Validate checks the announce prover pause.
|
||||
func (t *AnnounceProverPause) Validate() error {
|
||||
if t == nil {
|
||||
return errors.New("nil announce prover pause")
|
||||
}
|
||||
if len(t.Filter) != 32 {
|
||||
return errors.New("invalid filter")
|
||||
}
|
||||
if err := t.PublicKeySignatureEd448.Validate(); err != nil {
|
||||
return errors.Wrap(err, "public key signature")
|
||||
}
|
||||
if err := t.ValidateSignature(); err != nil {
|
||||
return errors.Wrap(err, "signature")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ ValidatableMessage = (*AnnounceProverResume)(nil)
|
||||
|
||||
// Validate checks the announce prover resume.
|
||||
func (t *AnnounceProverResume) Validate() error {
|
||||
if t == nil {
|
||||
return errors.New("nil announce prover resume")
|
||||
}
|
||||
if len(t.Filter) != 32 {
|
||||
return errors.New("invalid filter")
|
||||
}
|
||||
if err := t.PublicKeySignatureEd448.Validate(); err != nil {
|
||||
return errors.Wrap(err, "public key signature")
|
||||
}
|
||||
if err := t.ValidateSignature(); err != nil {
|
||||
return errors.Wrap(err, "signature")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SignableED448Message is a message that can be signed.
|
||||
type SignableED448Message interface {
|
||||
// SignED448 signs the message with the given key, modifying the message.
|
||||
// The message contents are expected to be valid - message
|
||||
// contents must be validated, or correctly constructed, before signing.
|
||||
SignED448(publicKey []byte, sign func([]byte) ([]byte, error)) error
|
||||
}
|
||||
|
||||
func newED448Signature(publicKey, signature []byte) *Ed448Signature {
|
||||
return &Ed448Signature{
|
||||
PublicKey: &Ed448PublicKey{
|
||||
KeyValue: publicKey,
|
||||
},
|
||||
Signature: signature,
|
||||
}
|
||||
}
|
||||
|
||||
var _ SignableED448Message = (*TransferCoinRequest)(nil)
|
||||
|
||||
// SignED448 signs the transfer coin request with the given key.
|
||||
func (t *TransferCoinRequest) SignED448(publicKey []byte, sign func([]byte) ([]byte, error)) error {
|
||||
signature, err := sign(t.signatureMessage())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "sign")
|
||||
}
|
||||
t.Signature = newED448Signature(publicKey, signature)
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ SignableED448Message = (*SplitCoinRequest)(nil)
|
||||
|
||||
// SignED448 signs the split coin request with the given key.
|
||||
func (t *SplitCoinRequest) SignED448(publicKey []byte, sign func([]byte) ([]byte, error)) error {
|
||||
signature, err := sign(t.signatureMessage())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "sign")
|
||||
}
|
||||
t.Signature = newED448Signature(publicKey, signature)
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ SignableED448Message = (*MergeCoinRequest)(nil)
|
||||
|
||||
// SignED448 signs the merge coin request with the given key.
|
||||
func (t *MergeCoinRequest) SignED448(publicKey []byte, sign func([]byte) ([]byte, error)) error {
|
||||
signature, err := sign(t.signatureMessage())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "sign")
|
||||
}
|
||||
t.Signature = newED448Signature(publicKey, signature)
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ SignableED448Message = (*MintCoinRequest)(nil)
|
||||
|
||||
// SignED448 signs the mint coin request with the given key.
|
||||
func (t *MintCoinRequest) SignED448(publicKey []byte, sign func([]byte) ([]byte, error)) error {
|
||||
signature, err := sign(t.signatureMessage())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "sign")
|
||||
}
|
||||
t.Signature = newED448Signature(publicKey, signature)
|
||||
return nil
|
||||
}
|
||||
|
||||
type ED448SignHelper struct {
|
||||
PublicKey []byte
|
||||
Sign func([]byte) ([]byte, error)
|
||||
}
|
||||
|
||||
// SignED448 signs the announce prover request with the given keys.
|
||||
func (t *AnnounceProverRequest) SignED448(helpers []ED448SignHelper) error {
|
||||
if len(helpers) == 0 {
|
||||
return errors.New("no keys")
|
||||
}
|
||||
payload := []byte{}
|
||||
primary := helpers[0]
|
||||
signatures := make([]*Ed448Signature, len(helpers))
|
||||
for i, k := range helpers[1:] {
|
||||
payload = append(payload, k.PublicKey...)
|
||||
signature, err := k.Sign(primary.PublicKey)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "sign")
|
||||
}
|
||||
signatures[i+1] = newED448Signature(k.PublicKey, signature)
|
||||
}
|
||||
signature, err := primary.Sign(payload)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "sign")
|
||||
}
|
||||
signatures[0] = newED448Signature(primary.PublicKey, signature)
|
||||
t.PublicKeySignaturesEd448 = signatures
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ SignableED448Message = (*AnnounceProverJoin)(nil)
|
||||
|
||||
// SignED448 signs the announce prover join with the given key.
|
||||
func (t *AnnounceProverJoin) SignED448(publicKey []byte, sign func([]byte) ([]byte, error)) error {
|
||||
signature, err := sign(t.signatureMessage())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "sign")
|
||||
}
|
||||
t.PublicKeySignatureEd448 = newED448Signature(publicKey, signature)
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ SignableED448Message = (*AnnounceProverLeave)(nil)
|
||||
|
||||
// SignED448 signs the announce prover leave with the given key.
|
||||
func (t *AnnounceProverLeave) SignED448(publicKey []byte, sign func([]byte) ([]byte, error)) error {
|
||||
signature, err := sign(t.signatureMessage())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "sign")
|
||||
}
|
||||
t.PublicKeySignatureEd448 = newED448Signature(publicKey, signature)
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ SignableED448Message = (*AnnounceProverPause)(nil)
|
||||
|
||||
// SignED448 signs the announce prover pause with the given key.
|
||||
func (t *AnnounceProverPause) SignED448(publicKey []byte, sign func([]byte) ([]byte, error)) error {
|
||||
signature, err := sign(t.signatureMessage())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "sign")
|
||||
}
|
||||
t.PublicKeySignatureEd448 = newED448Signature(publicKey, signature)
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ SignableED448Message = (*AnnounceProverResume)(nil)
|
||||
|
||||
// SignED448 signs the announce prover resume with the given key.
|
||||
func (t *AnnounceProverResume) SignED448(publicKey []byte, sign func([]byte) ([]byte, error)) error {
|
||||
signature, err := sign(t.signatureMessage())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "sign")
|
||||
}
|
||||
t.PublicKeySignatureEd448 = newED448Signature(publicKey, signature)
|
||||
return nil
|
||||
}
|
||||
5
node/protobufs/validation_internal_test.go
Normal file
5
node/protobufs/validation_internal_test.go
Normal file
@ -0,0 +1,5 @@
|
||||
package protobufs
|
||||
|
||||
func SignatureMessageOf(m any) []byte {
|
||||
return m.(signatureMessage).signatureMessage()
|
||||
}
|
||||
914
node/protobufs/validation_test.go
Normal file
914
node/protobufs/validation_test.go
Normal file
@ -0,0 +1,914 @@
|
||||
package protobufs_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/libp2p/go-libp2p/core/crypto"
|
||||
"source.quilibrium.com/quilibrium/monorepo/node/protobufs"
|
||||
)
|
||||
|
||||
func newPrivateKey() crypto.PrivKey {
|
||||
privKey, _, err := crypto.GenerateEd448Key(rand.Reader)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return privKey
|
||||
}
|
||||
|
||||
func publicKeyBytesOf(privKey crypto.PrivKey) []byte {
|
||||
b, err := privKey.GetPublic().Raw()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
var (
|
||||
primaryPrivateKey crypto.PrivKey = newPrivateKey()
|
||||
primaryPublicKeyBytes []byte = publicKeyBytesOf(primaryPrivateKey)
|
||||
|
||||
secondaryPrivateKey crypto.PrivKey = newPrivateKey()
|
||||
secondaryPublicKeyBytes []byte = publicKeyBytesOf(secondaryPrivateKey)
|
||||
)
|
||||
|
||||
func metaAppend[T any](bs ...[]T) []T {
|
||||
var result []T
|
||||
for _, b := range bs {
|
||||
result = append(result, b...)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func TestTransferCoinRequestSignatureRoundtrip(t *testing.T) {
|
||||
t.Parallel()
|
||||
message := &protobufs.TransferCoinRequest{
|
||||
OfCoin: &protobufs.CoinRef{
|
||||
Address: bytes.Repeat([]byte{0x01}, 32),
|
||||
},
|
||||
ToAccount: &protobufs.AccountRef{
|
||||
Account: &protobufs.AccountRef_ImplicitAccount{
|
||||
ImplicitAccount: &protobufs.ImplicitAccount{
|
||||
Address: bytes.Repeat([]byte{0x02}, 32),
|
||||
},
|
||||
},
|
||||
},
|
||||
Signature: &protobufs.Ed448Signature{
|
||||
Signature: bytes.Repeat([]byte{0x03}, 114),
|
||||
PublicKey: &protobufs.Ed448PublicKey{
|
||||
KeyValue: bytes.Repeat([]byte{0x04}, 57),
|
||||
},
|
||||
},
|
||||
}
|
||||
if !bytes.Equal(
|
||||
protobufs.SignatureMessageOf(message),
|
||||
metaAppend(
|
||||
[]byte("transfer"),
|
||||
bytes.Repeat([]byte{0x01}, 32),
|
||||
bytes.Repeat([]byte{0x02}, 32),
|
||||
),
|
||||
) {
|
||||
t.Fatal("unexpected signature message")
|
||||
}
|
||||
if err := message.ValidateSignature(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
if err := message.SignED448(primaryPublicKeyBytes, primaryPrivateKey.Sign); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(message.Signature.PublicKey.KeyValue, primaryPublicKeyBytes) {
|
||||
t.Fatal("unexpected public key")
|
||||
}
|
||||
if err := message.ValidateSignature(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSplitCoinRequestSignatureRoundtrip(t *testing.T) {
|
||||
t.Parallel()
|
||||
message := &protobufs.SplitCoinRequest{
|
||||
OfCoin: &protobufs.CoinRef{
|
||||
Address: bytes.Repeat([]byte{0x01}, 32),
|
||||
},
|
||||
Amounts: [][]byte{
|
||||
bytes.Repeat([]byte{0x02}, 32),
|
||||
bytes.Repeat([]byte{0x03}, 32),
|
||||
},
|
||||
Signature: &protobufs.Ed448Signature{
|
||||
Signature: bytes.Repeat([]byte{0x04}, 114),
|
||||
PublicKey: &protobufs.Ed448PublicKey{
|
||||
KeyValue: bytes.Repeat([]byte{0x05}, 57),
|
||||
},
|
||||
},
|
||||
}
|
||||
if !bytes.Equal(
|
||||
protobufs.SignatureMessageOf(message),
|
||||
metaAppend(
|
||||
[]byte("split"),
|
||||
bytes.Repeat([]byte{0x01}, 32),
|
||||
bytes.Repeat([]byte{0x02}, 32),
|
||||
bytes.Repeat([]byte{0x03}, 32),
|
||||
),
|
||||
) {
|
||||
t.Fatal("unexpected signature message")
|
||||
}
|
||||
if err := message.ValidateSignature(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
if err := message.SignED448(primaryPublicKeyBytes, primaryPrivateKey.Sign); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(message.Signature.PublicKey.KeyValue, primaryPublicKeyBytes) {
|
||||
t.Fatal("unexpected public key")
|
||||
}
|
||||
if err := message.ValidateSignature(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMergeCoinRequestSignatureRoundtrip(t *testing.T) {
|
||||
t.Parallel()
|
||||
message := &protobufs.MergeCoinRequest{
|
||||
Coins: []*protobufs.CoinRef{
|
||||
{
|
||||
Address: bytes.Repeat([]byte{0x01}, 32),
|
||||
},
|
||||
{
|
||||
Address: bytes.Repeat([]byte{0x02}, 32),
|
||||
},
|
||||
},
|
||||
Signature: &protobufs.Ed448Signature{
|
||||
Signature: bytes.Repeat([]byte{0x03}, 114),
|
||||
PublicKey: &protobufs.Ed448PublicKey{
|
||||
KeyValue: bytes.Repeat([]byte{0x04}, 57),
|
||||
},
|
||||
},
|
||||
}
|
||||
if !bytes.Equal(
|
||||
protobufs.SignatureMessageOf(message),
|
||||
metaAppend(
|
||||
[]byte("merge"),
|
||||
bytes.Repeat([]byte{0x01}, 32),
|
||||
bytes.Repeat([]byte{0x02}, 32),
|
||||
),
|
||||
) {
|
||||
t.Fatal("unexpected signature message")
|
||||
}
|
||||
if err := message.ValidateSignature(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
if err := message.SignED448(primaryPublicKeyBytes, primaryPrivateKey.Sign); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(message.Signature.PublicKey.KeyValue, primaryPublicKeyBytes) {
|
||||
t.Fatal("unexpected public key")
|
||||
}
|
||||
if err := message.ValidateSignature(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMintCoinRequestSignatureRoundtrip(t *testing.T) {
|
||||
t.Parallel()
|
||||
message := &protobufs.MintCoinRequest{
|
||||
Proofs: [][]byte{
|
||||
bytes.Repeat([]byte{0x01}, 32),
|
||||
bytes.Repeat([]byte{0x02}, 32),
|
||||
},
|
||||
Signature: &protobufs.Ed448Signature{
|
||||
Signature: bytes.Repeat([]byte{0x03}, 114),
|
||||
PublicKey: &protobufs.Ed448PublicKey{
|
||||
KeyValue: bytes.Repeat([]byte{0x04}, 57),
|
||||
},
|
||||
},
|
||||
}
|
||||
if !bytes.Equal(
|
||||
protobufs.SignatureMessageOf(message),
|
||||
metaAppend(
|
||||
[]byte("mint"),
|
||||
bytes.Repeat([]byte{0x01}, 32),
|
||||
bytes.Repeat([]byte{0x02}, 32),
|
||||
),
|
||||
) {
|
||||
t.Fatal("unexpected signature message")
|
||||
}
|
||||
if err := message.ValidateSignature(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
if err := message.SignED448(primaryPublicKeyBytes, primaryPrivateKey.Sign); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(message.Signature.PublicKey.KeyValue, primaryPublicKeyBytes) {
|
||||
t.Fatal("unexpected public key")
|
||||
}
|
||||
if err := message.ValidateSignature(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAnnounceProverRequestSignatureRoundtrip(t *testing.T) {
|
||||
t.Parallel()
|
||||
message := &protobufs.AnnounceProverRequest{
|
||||
PublicKeySignaturesEd448: []*protobufs.Ed448Signature{
|
||||
{
|
||||
Signature: bytes.Repeat([]byte{0x01}, 114),
|
||||
PublicKey: &protobufs.Ed448PublicKey{
|
||||
KeyValue: bytes.Repeat([]byte{0x02}, 57),
|
||||
},
|
||||
},
|
||||
{
|
||||
Signature: bytes.Repeat([]byte{0x03}, 114),
|
||||
PublicKey: &protobufs.Ed448PublicKey{
|
||||
KeyValue: bytes.Repeat([]byte{0x04}, 57),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
if err := message.ValidateSignature(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
if err := message.SignED448([]protobufs.ED448SignHelper{
|
||||
{
|
||||
PublicKey: primaryPublicKeyBytes,
|
||||
Sign: primaryPrivateKey.Sign,
|
||||
},
|
||||
{
|
||||
PublicKey: secondaryPublicKeyBytes,
|
||||
Sign: secondaryPrivateKey.Sign,
|
||||
},
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(message.PublicKeySignaturesEd448[0].PublicKey.KeyValue, primaryPublicKeyBytes) {
|
||||
t.Fatal("unexpected public key")
|
||||
}
|
||||
if !bytes.Equal(message.PublicKeySignaturesEd448[1].PublicKey.KeyValue, secondaryPublicKeyBytes) {
|
||||
t.Fatal("unexpected public key")
|
||||
}
|
||||
if err := message.ValidateSignature(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
message = &protobufs.AnnounceProverRequest{
|
||||
PublicKeySignaturesEd448: []*protobufs.Ed448Signature{
|
||||
{
|
||||
Signature: bytes.Repeat([]byte{0x01}, 114),
|
||||
PublicKey: &protobufs.Ed448PublicKey{
|
||||
KeyValue: bytes.Repeat([]byte{0x02}, 57),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
if err := message.ValidateSignature(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
if err := message.SignED448([]protobufs.ED448SignHelper{
|
||||
{
|
||||
PublicKey: primaryPublicKeyBytes,
|
||||
Sign: primaryPrivateKey.Sign,
|
||||
},
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(message.PublicKeySignaturesEd448[0].PublicKey.KeyValue, primaryPublicKeyBytes) {
|
||||
t.Fatal("unexpected public key")
|
||||
}
|
||||
if err := message.ValidateSignature(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAnnounceProverJoinSignatureRoundtrip(t *testing.T) {
|
||||
t.Parallel()
|
||||
message := &protobufs.AnnounceProverJoin{
|
||||
Filter: bytes.Repeat([]byte{0x01}, 32),
|
||||
FrameNumber: 1,
|
||||
PublicKeySignatureEd448: &protobufs.Ed448Signature{
|
||||
Signature: bytes.Repeat([]byte{0x02}, 114),
|
||||
PublicKey: &protobufs.Ed448PublicKey{
|
||||
KeyValue: bytes.Repeat([]byte{0x03}, 57),
|
||||
},
|
||||
},
|
||||
}
|
||||
if !bytes.Equal(
|
||||
protobufs.SignatureMessageOf(message),
|
||||
metaAppend(
|
||||
[]byte("join"),
|
||||
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
|
||||
bytes.Repeat([]byte{0x01}, 32),
|
||||
),
|
||||
) {
|
||||
t.Fatal("unexpected signature message")
|
||||
}
|
||||
if err := message.ValidateSignature(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
if err := message.SignED448(primaryPublicKeyBytes, primaryPrivateKey.Sign); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(message.PublicKeySignatureEd448.PublicKey.KeyValue, primaryPublicKeyBytes) {
|
||||
t.Fatal("unexpected public key")
|
||||
}
|
||||
if err := message.ValidateSignature(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAnnounceProverLeaveSignatureRoundtrip(t *testing.T) {
|
||||
t.Parallel()
|
||||
message := &protobufs.AnnounceProverLeave{
|
||||
Filter: bytes.Repeat([]byte{0x01}, 32),
|
||||
FrameNumber: 1,
|
||||
PublicKeySignatureEd448: &protobufs.Ed448Signature{
|
||||
Signature: bytes.Repeat([]byte{0x02}, 114),
|
||||
PublicKey: &protobufs.Ed448PublicKey{
|
||||
KeyValue: bytes.Repeat([]byte{0x03}, 57),
|
||||
},
|
||||
},
|
||||
}
|
||||
if !bytes.Equal(
|
||||
protobufs.SignatureMessageOf(message),
|
||||
metaAppend(
|
||||
[]byte("leave"),
|
||||
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
|
||||
bytes.Repeat([]byte{0x01}, 32),
|
||||
),
|
||||
) {
|
||||
t.Fatal("unexpected signature message")
|
||||
}
|
||||
if err := message.ValidateSignature(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
if err := message.SignED448(primaryPublicKeyBytes, primaryPrivateKey.Sign); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(message.PublicKeySignatureEd448.PublicKey.KeyValue, primaryPublicKeyBytes) {
|
||||
t.Fatal("unexpected public key")
|
||||
}
|
||||
if err := message.ValidateSignature(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAnnounceProverPauseSignatureRoundtrip(t *testing.T) {
|
||||
t.Parallel()
|
||||
message := &protobufs.AnnounceProverPause{
|
||||
Filter: bytes.Repeat([]byte{0x01}, 32),
|
||||
FrameNumber: 1,
|
||||
PublicKeySignatureEd448: &protobufs.Ed448Signature{
|
||||
Signature: bytes.Repeat([]byte{0x02}, 114),
|
||||
PublicKey: &protobufs.Ed448PublicKey{
|
||||
KeyValue: bytes.Repeat([]byte{0x03}, 57),
|
||||
},
|
||||
},
|
||||
}
|
||||
if !bytes.Equal(
|
||||
protobufs.SignatureMessageOf(message),
|
||||
metaAppend(
|
||||
[]byte("pause"),
|
||||
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
|
||||
bytes.Repeat([]byte{0x01}, 32),
|
||||
),
|
||||
) {
|
||||
t.Fatal("unexpected signature message")
|
||||
}
|
||||
if err := message.ValidateSignature(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
if err := message.SignED448(primaryPublicKeyBytes, primaryPrivateKey.Sign); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(message.PublicKeySignatureEd448.PublicKey.KeyValue, primaryPublicKeyBytes) {
|
||||
t.Fatal("unexpected public key")
|
||||
}
|
||||
if err := message.ValidateSignature(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAnnounceProverResumeSignatureRoundtrip(t *testing.T) {
|
||||
t.Parallel()
|
||||
message := &protobufs.AnnounceProverResume{
|
||||
Filter: bytes.Repeat([]byte{0x01}, 32),
|
||||
FrameNumber: 1,
|
||||
PublicKeySignatureEd448: &protobufs.Ed448Signature{
|
||||
Signature: bytes.Repeat([]byte{0x02}, 114),
|
||||
PublicKey: &protobufs.Ed448PublicKey{
|
||||
KeyValue: bytes.Repeat([]byte{0x03}, 57),
|
||||
},
|
||||
},
|
||||
}
|
||||
if !bytes.Equal(
|
||||
protobufs.SignatureMessageOf(message),
|
||||
metaAppend(
|
||||
[]byte("resume"),
|
||||
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
|
||||
bytes.Repeat([]byte{0x01}, 32),
|
||||
),
|
||||
) {
|
||||
t.Fatal("unexpected signature message")
|
||||
}
|
||||
if err := message.ValidateSignature(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
if err := message.SignED448(primaryPublicKeyBytes, primaryPrivateKey.Sign); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(message.PublicKeySignatureEd448.PublicKey.KeyValue, primaryPublicKeyBytes) {
|
||||
t.Fatal("unexpected public key")
|
||||
}
|
||||
if err := message.ValidateSignature(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEd448PublicKeyValidate(t *testing.T) {
|
||||
t.Parallel()
|
||||
if err := (*protobufs.Ed448PublicKey)(nil).Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
message := &protobufs.Ed448PublicKey{}
|
||||
if err := message.Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
message.KeyValue = bytes.Repeat([]byte{0x01}, 57)
|
||||
if err := message.Validate(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEd448SignatureValidate(t *testing.T) {
|
||||
t.Parallel()
|
||||
if err := (*protobufs.Ed448Signature)(nil).Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
message := &protobufs.Ed448Signature{}
|
||||
if err := message.Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
message.Signature = bytes.Repeat([]byte{0x01}, 114)
|
||||
message.PublicKey = &protobufs.Ed448PublicKey{
|
||||
KeyValue: bytes.Repeat([]byte{0x02}, 57),
|
||||
}
|
||||
if err := message.Validate(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestImplicitAccountValidate(t *testing.T) {
|
||||
t.Parallel()
|
||||
if err := (*protobufs.ImplicitAccount)(nil).Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
message := &protobufs.ImplicitAccount{}
|
||||
if err := message.Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
message.Address = bytes.Repeat([]byte{0x01}, 32)
|
||||
if err := message.Validate(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestOriginatedAccountRefValidate(t *testing.T) {
|
||||
t.Parallel()
|
||||
if err := (*protobufs.OriginatedAccountRef)(nil).Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
message := &protobufs.OriginatedAccountRef{}
|
||||
if err := message.Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
message.Address = bytes.Repeat([]byte{0x01}, 32)
|
||||
if err := message.Validate(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAccountRefValidate(t *testing.T) {
|
||||
t.Parallel()
|
||||
message := &protobufs.AccountRef{}
|
||||
if err := message.Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
message.Account = &protobufs.AccountRef_ImplicitAccount{
|
||||
ImplicitAccount: &protobufs.ImplicitAccount{
|
||||
Address: bytes.Repeat([]byte{0x01}, 32),
|
||||
},
|
||||
}
|
||||
if err := message.Validate(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
message.Account = &protobufs.AccountRef_OriginatedAccount{
|
||||
OriginatedAccount: &protobufs.OriginatedAccountRef{
|
||||
Address: bytes.Repeat([]byte{0x02}, 32),
|
||||
},
|
||||
}
|
||||
if err := message.Validate(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCoinRefValidate(t *testing.T) {
|
||||
t.Parallel()
|
||||
if err := (*protobufs.CoinRef)(nil).Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
message := &protobufs.CoinRef{}
|
||||
if err := message.Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
message.Address = bytes.Repeat([]byte{0x01}, 32)
|
||||
if err := message.Validate(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAccountAllowanceRefValidate(t *testing.T) {
|
||||
t.Parallel()
|
||||
if err := (*protobufs.AccountAllowanceRef)(nil).Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
message := &protobufs.AccountAllowanceRef{}
|
||||
if err := message.Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
message.Address = bytes.Repeat([]byte{0x01}, 32)
|
||||
if err := message.Validate(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCoinAllowanceRefValidate(t *testing.T) {
|
||||
t.Parallel()
|
||||
if err := (*protobufs.CoinAllowanceRef)(nil).Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
message := &protobufs.CoinAllowanceRef{}
|
||||
if err := message.Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
message.Address = bytes.Repeat([]byte{0x01}, 32)
|
||||
if err := message.Validate(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTransferCoinRequestValidate(t *testing.T) {
|
||||
t.Parallel()
|
||||
if err := (*protobufs.TransferCoinRequest)(nil).Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
message := &protobufs.TransferCoinRequest{}
|
||||
if err := message.Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
if err := (&protobufs.TokenRequest{
|
||||
Request: &protobufs.TokenRequest_Transfer{
|
||||
Transfer: message,
|
||||
},
|
||||
}).Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
message.OfCoin = &protobufs.CoinRef{
|
||||
Address: bytes.Repeat([]byte{0x01}, 32),
|
||||
}
|
||||
message.ToAccount = &protobufs.AccountRef{
|
||||
Account: &protobufs.AccountRef_ImplicitAccount{
|
||||
ImplicitAccount: &protobufs.ImplicitAccount{
|
||||
Address: bytes.Repeat([]byte{0x02}, 32),
|
||||
},
|
||||
},
|
||||
}
|
||||
if err := message.SignED448(primaryPublicKeyBytes, primaryPrivateKey.Sign); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := message.Validate(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := (&protobufs.TokenRequest{
|
||||
Request: &protobufs.TokenRequest_Transfer{
|
||||
Transfer: message,
|
||||
},
|
||||
}).Validate(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSplitCoinRequestValidate(t *testing.T) {
|
||||
t.Parallel()
|
||||
if err := (*protobufs.SplitCoinRequest)(nil).Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
message := &protobufs.SplitCoinRequest{}
|
||||
if err := message.Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
if err := (&protobufs.TokenRequest{
|
||||
Request: &protobufs.TokenRequest_Split{
|
||||
Split: message,
|
||||
},
|
||||
}).Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
message.OfCoin = &protobufs.CoinRef{
|
||||
Address: bytes.Repeat([]byte{0x01}, 32),
|
||||
}
|
||||
message.Amounts = [][]byte{
|
||||
bytes.Repeat([]byte{0x02}, 32),
|
||||
bytes.Repeat([]byte{0x03}, 32),
|
||||
}
|
||||
if err := message.SignED448(primaryPublicKeyBytes, primaryPrivateKey.Sign); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := message.Validate(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := (&protobufs.TokenRequest{
|
||||
Request: &protobufs.TokenRequest_Split{
|
||||
Split: message,
|
||||
},
|
||||
}).Validate(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMergeCoinRequestValidate(t *testing.T) {
|
||||
t.Parallel()
|
||||
if err := (*protobufs.MergeCoinRequest)(nil).Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
message := &protobufs.MergeCoinRequest{}
|
||||
if err := message.Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
if err := (&protobufs.TokenRequest{
|
||||
Request: &protobufs.TokenRequest_Merge{
|
||||
Merge: message,
|
||||
},
|
||||
}).Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
message.Coins = []*protobufs.CoinRef{
|
||||
{
|
||||
Address: bytes.Repeat([]byte{0x01}, 32),
|
||||
},
|
||||
{
|
||||
Address: bytes.Repeat([]byte{0x02}, 32),
|
||||
},
|
||||
}
|
||||
if err := message.SignED448(primaryPublicKeyBytes, primaryPrivateKey.Sign); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := message.Validate(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := (&protobufs.TokenRequest{
|
||||
Request: &protobufs.TokenRequest_Merge{
|
||||
Merge: message,
|
||||
},
|
||||
}).Validate(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMintCoinRequestValidate(t *testing.T) {
|
||||
t.Parallel()
|
||||
if err := (*protobufs.MintCoinRequest)(nil).Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
message := &protobufs.MintCoinRequest{}
|
||||
if err := message.Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
if err := (&protobufs.TokenRequest{
|
||||
Request: &protobufs.TokenRequest_Mint{
|
||||
Mint: message,
|
||||
},
|
||||
}).Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
message.Proofs = [][]byte{
|
||||
bytes.Repeat([]byte{0x01}, 32),
|
||||
bytes.Repeat([]byte{0x02}, 32),
|
||||
}
|
||||
if err := message.SignED448(primaryPublicKeyBytes, primaryPrivateKey.Sign); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := message.Validate(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := (&protobufs.TokenRequest{
|
||||
Request: &protobufs.TokenRequest_Mint{
|
||||
Mint: message,
|
||||
},
|
||||
}).Validate(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAnnounceProverRequestValidate(t *testing.T) {
|
||||
t.Parallel()
|
||||
if err := (*protobufs.AnnounceProverRequest)(nil).Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
message := &protobufs.AnnounceProverRequest{}
|
||||
if err := message.Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
if err := (&protobufs.TokenRequest{
|
||||
Request: &protobufs.TokenRequest_Announce{
|
||||
Announce: message,
|
||||
},
|
||||
}).Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
if err := message.SignED448([]protobufs.ED448SignHelper{
|
||||
{
|
||||
PublicKey: primaryPublicKeyBytes,
|
||||
Sign: primaryPrivateKey.Sign,
|
||||
},
|
||||
{
|
||||
PublicKey: secondaryPublicKeyBytes,
|
||||
Sign: secondaryPrivateKey.Sign,
|
||||
},
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := message.Validate(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := (&protobufs.TokenRequest{
|
||||
Request: &protobufs.TokenRequest_Announce{
|
||||
Announce: message,
|
||||
},
|
||||
}).Validate(); err != nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAnnounceProverJoinValidate(t *testing.T) {
|
||||
t.Parallel()
|
||||
if err := (*protobufs.AnnounceProverJoin)(nil).Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
message := &protobufs.AnnounceProverJoin{}
|
||||
if err := message.Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
if err := (&protobufs.TokenRequest{
|
||||
Request: &protobufs.TokenRequest_Join{
|
||||
Join: message,
|
||||
},
|
||||
}).Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
message.Filter = bytes.Repeat([]byte{0x01}, 32)
|
||||
message.FrameNumber = 1
|
||||
if err := message.SignED448(primaryPublicKeyBytes, primaryPrivateKey.Sign); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := message.Validate(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := (&protobufs.TokenRequest{
|
||||
Request: &protobufs.TokenRequest_Join{
|
||||
Join: message,
|
||||
},
|
||||
}).Validate(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
announce := &protobufs.AnnounceProverRequest{}
|
||||
message.Announce = announce
|
||||
if err := message.Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
if err := (&protobufs.TokenRequest{
|
||||
Request: &protobufs.TokenRequest_Join{
|
||||
Join: message,
|
||||
},
|
||||
}).Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
if err := announce.SignED448([]protobufs.ED448SignHelper{
|
||||
{
|
||||
PublicKey: primaryPublicKeyBytes,
|
||||
Sign: primaryPrivateKey.Sign,
|
||||
},
|
||||
{
|
||||
PublicKey: secondaryPublicKeyBytes,
|
||||
Sign: secondaryPrivateKey.Sign,
|
||||
},
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := message.Validate(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := (&protobufs.TokenRequest{
|
||||
Request: &protobufs.TokenRequest_Join{
|
||||
Join: message,
|
||||
},
|
||||
}).Validate(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAnnounceProverLeaveValidate(t *testing.T) {
|
||||
t.Parallel()
|
||||
if err := (*protobufs.AnnounceProverLeave)(nil).Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
message := &protobufs.AnnounceProverLeave{}
|
||||
if err := message.Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
if err := (&protobufs.TokenRequest{
|
||||
Request: &protobufs.TokenRequest_Leave{
|
||||
Leave: message,
|
||||
},
|
||||
}).Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
message.Filter = bytes.Repeat([]byte{0x01}, 32)
|
||||
message.FrameNumber = 1
|
||||
if err := message.SignED448(primaryPublicKeyBytes, primaryPrivateKey.Sign); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := message.Validate(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := (&protobufs.TokenRequest{
|
||||
Request: &protobufs.TokenRequest_Leave{
|
||||
Leave: message,
|
||||
},
|
||||
}).Validate(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAnnounceProverPauseValidate(t *testing.T) {
|
||||
t.Parallel()
|
||||
if err := (*protobufs.AnnounceProverPause)(nil).Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
message := &protobufs.AnnounceProverPause{}
|
||||
if err := message.Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
if err := (&protobufs.TokenRequest{
|
||||
Request: &protobufs.TokenRequest_Pause{
|
||||
Pause: message,
|
||||
},
|
||||
}).Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
message.Filter = bytes.Repeat([]byte{0x01}, 32)
|
||||
message.FrameNumber = 1
|
||||
if err := message.SignED448(primaryPublicKeyBytes, primaryPrivateKey.Sign); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := message.Validate(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := (&protobufs.TokenRequest{
|
||||
Request: &protobufs.TokenRequest_Pause{
|
||||
Pause: message,
|
||||
},
|
||||
}).Validate(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAnnounceProverResumeValidate(t *testing.T) {
|
||||
t.Parallel()
|
||||
if err := (*protobufs.AnnounceProverResume)(nil).Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
message := &protobufs.AnnounceProverResume{}
|
||||
if err := message.Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
if err := (&protobufs.TokenRequest{
|
||||
Request: &protobufs.TokenRequest_Resume{
|
||||
Resume: message,
|
||||
},
|
||||
}).Validate(); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
message.Filter = bytes.Repeat([]byte{0x01}, 32)
|
||||
message.FrameNumber = 1
|
||||
if err := message.SignED448(primaryPublicKeyBytes, primaryPrivateKey.Sign); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := message.Validate(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := (&protobufs.TokenRequest{
|
||||
Request: &protobufs.TokenRequest_Resume{
|
||||
Resume: message,
|
||||
},
|
||||
}).Validate(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
@ -221,20 +221,20 @@ func (r *RPCServer) SendMessage(
|
||||
) (*protobufs.SendMessageResponse, error) {
|
||||
req.Timestamp = time.Now().UnixMilli()
|
||||
|
||||
any := &anypb.Any{}
|
||||
if err := any.MarshalFrom(req); err != nil {
|
||||
a := &anypb.Any{}
|
||||
if err := a.MarshalFrom(req); err != nil {
|
||||
return nil, errors.Wrap(err, "publish message")
|
||||
}
|
||||
|
||||
// annoying protobuf any hack
|
||||
any.TypeUrl = strings.Replace(
|
||||
any.TypeUrl,
|
||||
a.TypeUrl = strings.Replace(
|
||||
a.TypeUrl,
|
||||
"type.googleapis.com",
|
||||
"types.quilibrium.com",
|
||||
1,
|
||||
)
|
||||
|
||||
payload, err := proto.Marshal(any)
|
||||
payload, err := proto.Marshal(a)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "publish message")
|
||||
}
|
||||
|
||||
@ -31,9 +31,9 @@ func PackOutputIntoPayloadAndProof(
|
||||
modulo int,
|
||||
frame *protobufs.ClockFrame,
|
||||
previousTree *mt.MerkleTree,
|
||||
) (*mt.MerkleTree, []byte, [][]byte, error) {
|
||||
) (*mt.MerkleTree, [][]byte, error) {
|
||||
if modulo != len(outputs) {
|
||||
return nil, nil, nil, errors.Wrap(
|
||||
return nil, nil, errors.Wrap(
|
||||
errors.New("mismatch of outputs and prover size"),
|
||||
"pack output into payload and proof",
|
||||
)
|
||||
@ -50,14 +50,9 @@ func PackOutputIntoPayloadAndProof(
|
||||
outputs,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, nil, nil, errors.Wrap(err, "pack output into payload and proof")
|
||||
return nil, nil, errors.Wrap(err, "pack output into payload and proof")
|
||||
}
|
||||
|
||||
payload := []byte("mint")
|
||||
payload = append(payload, tree.Root...)
|
||||
payload = binary.BigEndian.AppendUint32(payload, uint32(modulo))
|
||||
payload = binary.BigEndian.AppendUint64(payload, frame.FrameNumber)
|
||||
|
||||
output := [][]byte{
|
||||
tree.Root,
|
||||
binary.BigEndian.AppendUint32([]byte{}, uint32(modulo)),
|
||||
@ -68,19 +63,14 @@ func PackOutputIntoPayloadAndProof(
|
||||
hash := sha3.Sum256(frame.Output)
|
||||
pick := BytesToUnbiasedMod(hash, uint64(modulo))
|
||||
if uint64(modulo) < pick {
|
||||
return nil, nil, nil, errors.Wrap(
|
||||
return nil, nil, errors.Wrap(
|
||||
errors.New("proof size mismatch"),
|
||||
"pack output into payload and proof",
|
||||
)
|
||||
}
|
||||
for _, sib := range previousTree.Proofs[int(pick)].Siblings {
|
||||
payload = append(payload, sib...)
|
||||
output = append(output, sib)
|
||||
}
|
||||
payload = binary.BigEndian.AppendUint32(
|
||||
payload,
|
||||
previousTree.Proofs[int(pick)].Path,
|
||||
)
|
||||
output = append(
|
||||
output,
|
||||
binary.BigEndian.AppendUint32(
|
||||
@ -88,10 +78,9 @@ func PackOutputIntoPayloadAndProof(
|
||||
previousTree.Proofs[int(pick)].Path,
|
||||
),
|
||||
)
|
||||
payload = append(payload, previousTree.Leaves[int(pick)]...)
|
||||
output = append(output, previousTree.Leaves[int(pick)])
|
||||
}
|
||||
return tree, payload, output, nil
|
||||
return tree, output, nil
|
||||
}
|
||||
|
||||
func UnpackAndVerifyOutput(
|
||||
|
||||
Loading…
Reference in New Issue
Block a user