Merge pull request #428 from XinFinOrg/dev-upgrade

Dev upgrade and bump version to 2.0.2
This commit is contained in:
Liam 2024-02-20 02:24:07 +11:00 committed by GitHub
commit 1720858916
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
36 changed files with 604 additions and 194 deletions

View file

@ -148,7 +148,6 @@ func (abi *ABI) MethodById(sigdata []byte) (*Method, error) {
return nil, fmt.Errorf("no method with id: %#x", sigdata[:4])
}
// revertSelector is a special function selector for revert reason unpacking.
var revertSelector = crypto.Keccak256([]byte("Error(string)"))[:4]

View file

@ -290,7 +290,7 @@ func capitalise(input string) string {
return strings.ToUpper(input[:1]) + input[1:]
}
//unpackStruct extracts each argument into its corresponding struct field
// unpackStruct extracts each argument into its corresponding struct field
func unpackStruct(value, reflectValue reflect.Value, arg Argument) error {
name := capitalise(arg.Name)
typ := value.Type()

View file

@ -30,6 +30,10 @@ import (
"github.com/XinFinOrg/XDPoSChain/event"
)
var (
errNoEventSignature = errors.New("no event signature")
)
// SignerFn is a signer function callback when a contract requires a method to
// sign the transaction before submission.
type SignerFn func(types.Signer, common.Address, *types.Transaction) (*types.Transaction, error)
@ -326,6 +330,13 @@ func (c *BoundContract) WatchLogs(opts *WatchOpts, name string, query ...[]inter
// UnpackLog unpacks a retrieved log into the provided output structure.
func (c *BoundContract) UnpackLog(out interface{}, event string, log types.Log) error {
// Anonymous events are not supported.
if len(log.Topics) == 0 {
return errNoEventSignature
}
if log.Topics[0] != c.abi.Events[event].Id() {
return fmt.Errorf("event signature mismatch")
}
if len(log.Data) > 0 {
if err := c.abi.Unpack(out, event, log.Data); err != nil {
return err

View file

@ -1,28 +1,16 @@
#!/bin/bash
# Update AWS Max Health can resolve below issue, and it's already addressed
# echo "Preparing to start the XDC chain, it's likely to take up to 1 minute"
# Sleep for > 30 as we need to wait for the ECS tasks container being killed by fargate. Otherwise it will ended up with two same nodes running on a single /work/xdcchain directory
# sleep 60
if [ ! -d /work/xdcchain/XDC/chaindata ]
then
# Randomly select a key from environment variable, seperated by ','
if test -z "$PRIVATE_KEYS"
if test -z "$PRIVATE_KEY"
then
echo "PRIVATE_KEYS environment variable has not been set. You need to pass at least one PK, or you can pass multiple PK seperated by ',', we will randomly choose one for you"
echo "PRIVATE_KEY environment variable has not been set."
exit 1
fi
IFS=', ' read -r -a private_keys <<< "$PRIVATE_KEYS"
private_key=${private_keys[ $RANDOM % ${#private_keys[@]} ]}
echo "${private_key}" >> /tmp/key
echo "Creating a new wallet"
wallet=$(XDC account import --password .pwd --datadir /work/xdcchain /tmp/key | awk -F '[{}]' '{print $2}')
echo $PRIVATE_KEY >> /tmp/key
wallet=$(XDC account import --password .pwd --datadir /work/xdcchain /tmp/key | awk -v FS="({|})" '{print $2}')
XDC --datadir /work/xdcchain init /work/genesis.json
else
echo "Wallet already exist, re-use the same one"
wallet=$(XDC account list --datadir /work/xdcchain | head -n 1 | awk -F '[{}]' '{print $2}')
wallet=$(XDC account list --datadir /work/xdcchain | head -n 1 | awk -v FS="({|})" '{print $2}')
fi
input="/work/bootnodes.list"

View file

@ -1,23 +1,16 @@
#!/bin/bash
if [ ! -d /work/xdcchain/XDC/chaindata ]
then
# Randomly select a key from environment variable, seperated by ','
if test -z "$PRIVATE_KEYS"
if test -z "$PRIVATE_KEY"
then
echo "PRIVATE_KEYS environment variable has not been set. You need to pass at least one PK, or you can pass multiple PK seperated by ',', we will randomly choose one for you"
echo "PRIVATE_KEY environment variable has not been set."
exit 1
fi
IFS=', ' read -r -a private_keys <<< "$PRIVATE_KEYS"
private_key=${private_keys[ $RANDOM % ${#private_keys[@]} ]}
echo "${private_key}" >> /tmp/key
echo "Creating a new wallet"
wallet=$(XDC account import --password .pwd --datadir /work/xdcchain /tmp/key | awk -F '[{}]' '{print $2}')
echo $PRIVATE_KEY >> /tmp/key
wallet=$(XDC account import --password .pwd --datadir /work/xdcchain /tmp/key | awk -v FS="({|})" '{print $2}')
XDC --datadir /work/xdcchain init /work/genesis.json
else
echo "Wallet already exist, re-use the same one"
wallet=$(XDC account list --datadir /work/xdcchain | head -n 1 | awk -F '[{}]' '{print $2}')
wallet=$(XDC account list --datadir /work/xdcchain | head -n 1 | awk -v FS="({|})" '{print $2}')
fi
input="/work/bootnodes.list"

View file

@ -2,22 +2,16 @@
if [ ! -d /work/xdcchain/XDC/chaindata ]
then
# Randomly select a key from environment variable, seperated by ','
if test -z "$PRIVATE_KEYS"
if test -z "$PRIVATE_KEY"
then
echo "PRIVATE_KEYS environment variable has not been set. You need to pass at least one PK, or you can pass multiple PK seperated by ',', we will randomly choose one for you"
echo "PRIVATE_KEY environment variable has not been set."
exit 1
fi
IFS=', ' read -r -a private_keys <<< "$PRIVATE_KEYS"
private_key=${private_keys[ $RANDOM % ${#private_keys[@]} ]}
echo "${private_key}" >> /tmp/key
echo "Creating a new wallet"
wallet=$(XDC account import --password .pwd --datadir /work/xdcchain /tmp/key | awk -F '[{}]' '{print $2}')
echo $PRIVATE_KEY >> /tmp/key
wallet=$(XDC account import --password .pwd --datadir /work/xdcchain /tmp/key | awk -v FS="({|})" '{print $2}')
XDC --datadir /work/xdcchain init /work/genesis.json
else
echo "Wallet already exist, re-use the same one"
wallet=$(XDC account list --datadir /work/xdcchain | head -n 1 | awk -F '[{}]' '{print $2}')
wallet=$(XDC account list --datadir /work/xdcchain | head -n 1 | awk -v FS="({|})" '{print $2}')
fi
input="/work/bootnodes.list"

View file

@ -451,6 +451,9 @@ func (x *XDPoS) GetSnapshot(chain consensus.ChainReader, header *types.Header) (
switch x.config.BlockConsensusVersion(header.Number, header.Extra, ExtraFieldCheck) {
case params.ConsensusEngineVersion2:
sp, err := x.EngineV2.GetSnapshot(chain, header)
if err != nil {
return nil, err
}
return &utils.PublicApiSnapshot{
Number: sp.Number,
Hash: sp.Hash,
@ -458,6 +461,9 @@ func (x *XDPoS) GetSnapshot(chain consensus.ChainReader, header *types.Header) (
}, err
default: // Default "v1"
sp, err := x.EngineV1.GetSnapshot(chain, header)
if err != nil {
return nil, err
}
// Convert to a standard PublicApiSnapshot type, otherwise it's a breaking change to API
return &utils.PublicApiSnapshot{
Number: sp.Number,

View file

@ -46,7 +46,7 @@ func (x *XDPoS_v2) yourturn(chain consensus.ChainReader, round types.Round, pare
curIndex := utils.Position(masterNodes, signer)
if curIndex == -1 {
log.Warn("[yourturn] I am not in masternodes list", "Hash", parent.Hash().Hex(), "signer", signer.Hex())
log.Debug("[yourturn] I am not in masternodes list", "Hash", parent.Hash().Hex(), "signer", signer.Hex())
return false, nil
}

View file

@ -161,6 +161,9 @@ func (x *XDPoS_v2) GetRoundNumber(header *types.Header) (types.Round, error) {
func (x *XDPoS_v2) GetSignersFromSnapshot(chain consensus.ChainReader, header *types.Header) ([]common.Address, error) {
snap, err := x.getSnapshot(chain, header.Number.Uint64(), false)
if err != nil {
return nil, err
}
return snap.NextEpochMasterNodes, err
}

View file

@ -830,7 +830,7 @@ func (ipp *InnerProdArg) Deserialize(proof []byte, numChallenges int) error {
if len(proof) <= (offset + 32*numChallenges) {
return errors.New("input data too short")
}
for i := 0; i < int(numChallenges); i++ {
for i := 0; i < numChallenges; i++ {
ipp.Challenges = append(ipp.Challenges, new(big.Int).SetBytes(proof[offset:offset+32]))
offset += 32
}

View file

@ -13,6 +13,8 @@ import (
"github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/crypto"
"github.com/XinFinOrg/XDPoSChain/crypto/secp256k1"
"github.com/XinFinOrg/XDPoSChain/log"
)
@ -259,6 +261,10 @@ func Deserialize(r []byte) (*RingSignature, error) {
sig.SerializedRing = r
if !Verify(sig, false) {
return nil, errors.New("failed to deserialize, invalid ring signature")
}
return sig, nil
}
@ -357,7 +363,8 @@ func Sign(m [32]byte, rings []Ring, privkeys []*ecdsa.PrivateKey, s int) (*RingS
for i := 0; i < numRing; i++ {
pubkeys[i] = &privkeys[i].PublicKey
}
curve := pubkeys[0].Curve
//cast to BitCurve used in go-eth since elliptic.Curve.Add() and elliptic.Curve.ScalarMult() is deprecated
curve := pubkeys[0].Curve.(*secp256k1.BitCurve)
sig := new(RingSignature)
sig.Size = ringsize
sig.NumRing = numRing
@ -447,6 +454,9 @@ func Sign(m [32]byte, rings []Ring, privkeys []*ecdsa.PrivateKey, s int) (*RingS
// calculate L[j][idx] = s[j][idx]*G + c[idx]*Ring[j][idx]
px, py := curve.ScalarMult(rings[j][idx].X, rings[j][idx].Y, PadTo32Bytes(C[idx].Bytes())) // px, py = c_i*P_i
sx, sy := curve.ScalarBaseMult(PadTo32Bytes(S[j][idx].Bytes())) // sx, sy = s[n-1]*G
if px == nil || py == nil || sx == nil || sy == nil {
return nil, errors.New("Could not create ring signature")
}
l_x, l_y := curve.Add(sx, sy, px, py)
L[j][idx] = &ecdsa.PublicKey{curve, l_x, l_y}
lT := append(PadTo32Bytes(l_x.Bytes()), PadTo32Bytes(l_y.Bytes())...)
@ -456,6 +466,9 @@ func Sign(m [32]byte, rings []Ring, privkeys []*ecdsa.PrivateKey, s int) (*RingS
px, py = curve.ScalarMult(images[j].X, images[j].Y, C[idx].Bytes()) // px, py = c_i*I
hx, hy := HashPoint(rings[j][idx])
sx, sy = curve.ScalarMult(hx, hy, S[j][idx].Bytes()) // sx, sy = s[n-1]*H_p(P_i)
if px == nil || py == nil || sx == nil || sy == nil {
return nil, errors.New("Could not create ring signature")
}
r_x, r_y := curve.Add(sx, sy, px, py)
R[j][idx] = &ecdsa.PublicKey{curve, r_x, r_y}
rT := append(PadTo32Bytes(r_x.Bytes()), PadTo32Bytes(r_y.Bytes())...)
@ -504,18 +517,41 @@ func Verify(sig *RingSignature, verifyMes bool) bool {
S := sig.S
C := make([]*big.Int, ringsize+1)
C[0] = sig.C
curve := sig.Curve
//cast to BitCurve used in go-eth since elliptic.Curve.Add() and elliptic.Curve.ScalarMult() is deprecated
curve := sig.Curve.(*secp256k1.BitCurve)
image := sig.I
//check on curve
for i := 0; i < numRing; i++ {
onCurve := curve.IsOnCurve(image[i].X, image[i].Y)
if !onCurve {
return false
}
for j := 0; j < ringsize; j++ {
onCurve := curve.IsOnCurve(rings[i][j].X, rings[i][j].Y)
if !onCurve {
return false
}
}
}
// calculate c[i+1] = H(m, s[i]*G + c[i]*P[i])
// and c[0] = H)(m, s[n-1]*G + c[n-1]*P[n-1]) where n is the ring size
//log.Info("C", "0", common.Bytes2Hex(C[0].Bytes()))
for j := 0; j < ringsize; j++ {
var l []byte
for i := 0; i < numRing; i++ {
// Validate S[i][j] and C[j]
if !isValidScalar(S[i][j], curve) || !isValidScalar(C[j], curve) {
return false // Or handle the error as required
}
// calculate L[i][j] = s[i][j]*G + c[j]*Ring[i][j]
px, py := curve.ScalarMult(rings[i][j].X, rings[i][j].Y, C[j].Bytes()) // px, py = c_i*P_i
sx, sy := curve.ScalarBaseMult(S[i][j].Bytes()) // sx, sy = s[i]*G
if px == nil || py == nil || sx == nil || sy == nil {
return false
}
l_x, l_y := curve.Add(sx, sy, px, py)
lT := append(PadTo32Bytes(l_x.Bytes()), PadTo32Bytes(l_y.Bytes())...)
//log.Info("L[i][j]", "i", i, "j", j, "L", common.Bytes2Hex(lT))
@ -524,9 +560,17 @@ func Verify(sig *RingSignature, verifyMes bool) bool {
// calculate R_i = s[i][j]*H_p(Ring[i][j]) + c[j]*I[j]
px, py = curve.ScalarMult(image[i].X, image[i].Y, C[j].Bytes()) // px, py = c[i]*I
hx, hy := HashPoint(rings[i][j])
// Validate S[i][j], hx, and hy
if !isValidScalar(S[i][j], curve) || !isValidScalar(hx, curve) || !isValidScalar(hy, curve) {
return false // Or handle the error as required
}
//log.Info("H[i][j]", "i", i, "j", j, "x.input", common.Bytes2Hex(rings[i][j].X.Bytes()), "y.input", common.Bytes2Hex(rings[i][j].Y.Bytes()))
//log.Info("H[i][j]", "i", i, "j", j, "x", common.Bytes2Hex(hx.Bytes()), "y", common.Bytes2Hex(hy.Bytes()))
sx, sy = curve.ScalarMult(hx, hy, S[i][j].Bytes()) // sx, sy = s[i]*H_p(P[i])
if px == nil || py == nil || sx == nil || sy == nil {
return false
}
r_x, r_y := curve.Add(sx, sy, px, py)
rT := append(PadTo32Bytes(r_x.Bytes()), PadTo32Bytes(r_y.Bytes())...)
//log.Info("R[i][j]", "i", i, "j", j, "L", common.Bytes2Hex(rT))
@ -549,6 +593,10 @@ func Verify(sig *RingSignature, verifyMes bool) bool {
return bytes.Equal(sig.C.Bytes(), C[ringsize].Bytes())
}
func isValidScalar(scalar *big.Int, curve elliptic.Curve) bool {
return scalar.Sign() >= 0 && scalar.Cmp(curve.Params().N) < 0
}
func Link(sig_a *RingSignature, sig_b *RingSignature) bool {
for i := 0; i < len(sig_a.I); i++ {
for j := 0; j < len(sig_b.I); j++ {

View file

@ -4,9 +4,13 @@ import (
"bytes"
"encoding/binary"
"fmt"
"math/big"
"testing"
"github.com/XinFinOrg/XDPoSChain/crypto"
"github.com/stretchr/testify/assert"
"github.com/XinFinOrg/XDPoSChain/crypto/secp256k1"
)
func TestSign(t *testing.T) {
@ -83,6 +87,62 @@ func TestDeserialize(t *testing.T) {
_, err = Deserialize(sig)
assert.EqualError(t, err, "incorrect ring size, len r: 3804, sig.NumRing: 5 sig.Size: 56759212534490939")
}
func TestVerify1(t *testing.T) {
numRing := 5
ringSize := 10
s := 7
rings, privkeys, m, err := GenerateMultiRingParams(numRing, ringSize, s)
if err != nil {
t.Error("fail to generate rings")
}
ringSignature, err := Sign(m, rings, privkeys, s)
if err != nil {
t.Error("fail to create ring signature")
}
sig, err := ringSignature.Serialize()
if err != nil {
t.Error("fail to serialize input ring signature")
}
deserializedSig, err := Deserialize(sig)
if err != nil {
t.Error("fail to deserialize ring signature")
}
assert.True(t, Verify(deserializedSig, false), "Verify should return true")
}
func TestDeserialize2(t *testing.T) {
numRing := 5
ringSize := 10
s := 7
rings, privkeys, m, err := GenerateMultiRingParams(numRing, ringSize, s)
if err != nil {
t.Error("fail to generate rings")
}
ringSignature, err := Sign(m, rings, privkeys, s)
if err != nil {
t.Error("fail to create ring signature")
}
// change one sig to the scalar field
ringSignature.S[0][0] = curve.Params().N
sig, err := ringSignature.Serialize()
if err != nil {
t.Error("fail to serialize input ring signature")
}
_, err = Deserialize(sig)
assert.EqualError(t, err, "failed to deserialize, invalid ring signature")
}
func TestPadTo32Bytes(t *testing.T) {
arr := [44]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34}
@ -127,3 +187,138 @@ func TestPadTo32Bytes(t *testing.T) {
assert.True(t, bytes.Equal(PadTo32Bytes(arr[10:40]), arr[8:40]), "Test PadTo32Bytes shorter than 32 bytes #9")
assert.True(t, bytes.Equal(PadTo32Bytes(arr[10:41]), arr[9:41]), "Test PadTo32Bytes shorter than 32 bytes #10")
}
func TestCurveAddNegative(t *testing.T) {
curve := crypto.S256().(*secp256k1.BitCurve)
x1, y1 := curve.ScalarBaseMult(new(big.Int).SetUint64(uint64(2)).Bytes())
fmt.Printf("Point(%x, %x)\n", x1, y1)
x2 := x1
y2 := new(big.Int).Neg(y1) // negative of point (x1,y1)
x3, y3 := curve.Add(x1, y1, x2, y2)
fmt.Printf("Output is Point(%x, %x)\n", x3, y3)
x0 := new(big.Int).SetUint64(uint64(0))
y0 := new(big.Int).SetUint64(uint64(0)) // infinity
if (x3.Cmp(x0) == 0) && (y3.Cmp(y0) == 0) {
// fmt.Printf("Correct, add negative of self should yield (0,0)")
} else {
t.Error("Incorrect, add negative of self did not yield (0,0)")
}
}
func TestCurveAddZero(t *testing.T) {
// curve := crypto.S256()
curve := crypto.S256().(*secp256k1.BitCurve)
x1, y1 := curve.ScalarBaseMult(new(big.Int).SetUint64(uint64(1)).Bytes())
fmt.Printf("Point(%x, %x)\n", x1, y1)
x0 := new(big.Int).SetUint64(uint64(0))
y0 := new(big.Int).SetUint64(uint64(0)) // infinity
fmt.Printf("Is point (%d,%d) on the curve: %t \n", x0, y0, curve.IsOnCurve(x0, y0))
x2, y2 := curve.Add(x1, y1, x0, y0)
fmt.Printf("Output is Point(%x, %x)\n", x2, y2)
if (x1.Cmp(x2) == 0) && (y1.Cmp(y2) == 0) {
// fmt.Printf("Correct, Point on curve is the same after Zero addition\n")
} else {
t.Error("Incorrect, Point on curve changed after Zero addition\n")
}
}
func TestOnCurveVerify(t *testing.T) {
numRing := 5
ringSize := 10
s := 5
rings, privkeys, m, err := GenerateMultiRingParams(numRing, ringSize, s)
ringSignature, err := Sign(m, rings, privkeys, s)
if err != nil {
t.Error("Failed to create Ring signature")
}
valid := Verify(ringSignature, false)
if !valid {
t.Error("Incorrect, unmodified ringSignature should be valid")
}
ringsModified := ringSignature.Ring
ringsModified[0][0].X = big.NewInt(1)
ringsModified[0][0].Y = big.NewInt(1)
valid = Verify(ringSignature, false)
if valid {
t.Error("Incorrect, modified ringSignature should be invalid")
}
}
func TestOnCurveDeserialize(t *testing.T) {
numRing := 5
ringSize := 10
s := 5
rings, privkeys, m, err := GenerateMultiRingParams(numRing, ringSize, s)
ringSignature, err := Sign(m, rings, privkeys, s)
if err != nil {
t.Error("Failed to create Ring signature")
}
sig, err := ringSignature.Serialize()
if err != nil {
t.Error("Failed to Serialize input Ring signature")
}
_, err = Deserialize(sig)
if err != nil {
t.Error("Failed to Deserialize")
}
ringsModified := ringSignature.Ring
ringsModified[0][0].X = big.NewInt(1)
ringsModified[0][0].Y = big.NewInt(1)
sig, err = ringSignature.Serialize()
if err != nil {
t.Error("Failed to Serialize input Ring signature")
}
_, err = Deserialize(sig)
assert.EqualError(t, err, "failed to deserialize, invalid ring signature")
}
func TestCurveScalarMult(t *testing.T) {
curve := crypto.S256().(*secp256k1.BitCurve)
x, y := curve.ScalarBaseMult(curve.Params().N.Bytes())
if x == nil && y == nil {
fmt.Println("Scalar multiplication with base point returns nil when scalar is the scalar field")
}
x2, y2 := curve.ScalarMult(new(big.Int).SetUint64(uint64(100)), new(big.Int).SetUint64(uint64(2)), curve.Params().N.Bytes())
if x2 == nil && y2 == nil {
fmt.Println("Scalar multiplication with a point (not necessarily on curve) returns nil when scalar is the scalar field")
}
}
func TestNilPointerDereferencePanic(t *testing.T) {
numRing := 5
ringSize := 10
s := 7
rings, privkeys, m, err := GenerateMultiRingParams(numRing, ringSize, s)
ringSig, err := Sign(m, rings, privkeys, s)
if err != nil {
fmt.Println("Failed to set up")
}
ringSig.S[0][0] = curve.Params().N // change one sig to the scalar field
sig, err := ringSig.Serialize()
if err != nil {
t.Error("Failed to Serialize input Ring signature")
}
_ , err = Deserialize(sig)
// Should failed to verify Ring signature as the signature is invalid
assert.EqualError(t, err, "failed to deserialize, invalid ring signature")
}

31
crypto/secp256k1/LICENSE Normal file
View file

@ -0,0 +1,31 @@
Copyright (c) 2010 The Go Authors. All rights reserved.
Copyright (c) 2011 ThePiachu. All rights reserved.
Copyright (c) 2015 Jeffrey Wilcke. All rights reserved.
Copyright (c) 2015 Felix Lange. All rights reserved.
Copyright (c) 2015 Gustav Simonsson. 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 the copyright holder. 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.

View file

@ -1,5 +1,6 @@
// Copyright 2010 The Go Authors. All rights reserved.
// Copyright 2011 ThePiachu. All rights reserved.
// Copyright 2015 Jeffrey Wilcke, Felix Lange, Gustav Simonsson. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@ -34,16 +35,28 @@ package secp256k1
import (
"crypto/elliptic"
"math/big"
"unsafe"
"github.com/XinFinOrg/XDPoSChain/common/math"
)
/*
#include "libsecp256k1/include/secp256k1.h"
extern int secp256k1_ext_scalar_mul(const secp256k1_context* ctx, const unsigned char *point, const unsigned char *scalar);
*/
import "C"
const (
// number of bits in a big.Word
wordBits = 32 << (uint64(^big.Word(0)) >> 63)
// number of bytes in a big.Word
wordBytes = wordBits / 8
)
// readBits encodes the absolute value of bigint as big-endian bytes. Callers
// must ensure that buf has enough space. If buf is too short the result will
// be incomplete.
func readBits(bigint *big.Int, buf []byte) {
i := len(buf)
for _, d := range bigint.Bits() {
for j := 0; j < wordBytes && i > 0; j++ {
i--
buf[i] = byte(d)
d >>= 8
}
}
}
// This code is from https://github.com/ThePiachu/GoBit and implements
// several Koblitz elliptic curves over prime fields.
@ -77,7 +90,7 @@ func (BitCurve *BitCurve) Params() *elliptic.CurveParams {
}
}
// IsOnBitCurve returns true if the given (x,y) lies on the BitCurve.
// IsOnCurve returns true if the given (x,y) lies on the BitCurve.
func (BitCurve *BitCurve) IsOnCurve(x, y *big.Int) bool {
// y² = x³ + b
y2 := new(big.Int).Mul(y, y) //y²
@ -92,7 +105,6 @@ func (BitCurve *BitCurve) IsOnCurve(x, y *big.Int) bool {
return x3.Cmp(y2) == 0
}
//TODO: double check if the function is okay
// affineFromJacobian reverses the Jacobian transform. See the comment at the
// top of the file.
func (BitCurve *BitCurve) affineFromJacobian(x, y, z *big.Int) (xOut, yOut *big.Int) {
@ -113,7 +125,18 @@ func (BitCurve *BitCurve) affineFromJacobian(x, y, z *big.Int) (xOut, yOut *big.
// Add returns the sum of (x1,y1) and (x2,y2)
func (BitCurve *BitCurve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) {
// If one point is at infinity, return the other point.
// Adding the point at infinity to any point will preserve the other point.
if x1.Sign() == 0 && y1.Sign() == 0 {
return x2, y2
}
if x2.Sign() == 0 && y2.Sign() == 0 {
return x1, y1
}
z := new(big.Int).SetInt64(1)
if x1.Cmp(x2) == 0 && y1.Cmp(y2) == 0 {
return BitCurve.affineFromJacobian(BitCurve.doubleJacobian(x1, y1, z))
}
return BitCurve.affineFromJacobian(BitCurve.addJacobian(x1, y1, z, x2, y2, z))
}
@ -222,40 +245,6 @@ func (BitCurve *BitCurve) doubleJacobian(x, y, z *big.Int) (*big.Int, *big.Int,
return x3, y3, z3
}
func (BitCurve *BitCurve) ScalarMult(Bx, By *big.Int, scalar []byte) (*big.Int, *big.Int) {
// Ensure scalar is exactly 32 bytes. We pad always, even if
// scalar is 32 bytes long, to avoid a timing side channel.
if len(scalar) > 32 {
panic("can't handle scalars > 256 bits")
}
// NOTE: potential timing issue
padded := make([]byte, 32)
copy(padded[32-len(scalar):], scalar)
scalar = padded
// Do the multiplication in C, updating point.
point := make([]byte, 64)
math.ReadBits(Bx, point[:32])
math.ReadBits(By, point[32:])
pointPtr := (*C.uchar)(unsafe.Pointer(&point[0]))
scalarPtr := (*C.uchar)(unsafe.Pointer(&scalar[0]))
res := C.secp256k1_ext_scalar_mul(context, pointPtr, scalarPtr)
// Unpack the result and clear temporaries.
x := new(big.Int).SetBytes(point[:32])
y := new(big.Int).SetBytes(point[32:])
for i := range point {
point[i] = 0
}
for i := range padded {
scalar[i] = 0
}
if res != 1 {
return nil, nil
}
return x, y
}
// ScalarBaseMult returns k*G, where G is the base point of the group and k is
// an integer in big-endian form.
func (BitCurve *BitCurve) ScalarBaseMult(k []byte) (*big.Int, *big.Int) {
@ -268,8 +257,8 @@ func (BitCurve *BitCurve) Marshal(x, y *big.Int) []byte {
byteLen := (BitCurve.BitSize + 7) >> 3
ret := make([]byte, 1+2*byteLen)
ret[0] = 4 // uncompressed point flag
math.ReadBits(x, ret[1:1+byteLen])
math.ReadBits(y, ret[1+byteLen:])
readBits(x, ret[1:1+byteLen])
readBits(y, ret[1+byteLen:])
return ret
}
@ -293,12 +282,12 @@ var theCurve = new(BitCurve)
func init() {
// See SEC 2 section 2.7.1
// curve parameters taken from:
// http://www.secg.org/collateral/sec2_final.pdf
theCurve.P, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 16)
theCurve.N, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 16)
theCurve.B, _ = new(big.Int).SetString("0000000000000000000000000000000000000000000000000000000000000007", 16)
theCurve.Gx, _ = new(big.Int).SetString("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 16)
theCurve.Gy, _ = new(big.Int).SetString("483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", 16)
// http://www.secg.org/sec2-v2.pdf
theCurve.P, _ = new(big.Int).SetString("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 0)
theCurve.N, _ = new(big.Int).SetString("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 0)
theCurve.B, _ = new(big.Int).SetString("0x0000000000000000000000000000000000000000000000000000000000000007", 0)
theCurve.Gx, _ = new(big.Int).SetString("0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 0)
theCurve.Gy, _ = new(big.Int).SetString("0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", 0)
theCurve.BitSize = 256
}

21
crypto/secp256k1/dummy.go Normal file
View file

@ -0,0 +1,21 @@
//go:build dummy
// +build dummy
// This file is part of a workaround for `go mod vendor` which won't vendor
// C files if there's no Go file in the same directory.
// This would prevent the crypto/secp256k1/libsecp256k1/include/secp256k1.h file to be vendored.
//
// This Go file imports the c directory where there is another dummy.go file which
// is the second part of this workaround.
//
// These two files combined make it so `go mod vendor` behaves correctly.
//
// See this issue for reference: https://github.com/golang/go/issues/26366
package secp256k1
import (
_ "github.com/ethereum/go-ethereum/crypto/secp256k1/libsecp256k1/include"
_ "github.com/ethereum/go-ethereum/crypto/secp256k1/libsecp256k1/src"
_ "github.com/ethereum/go-ethereum/crypto/secp256k1/libsecp256k1/src/modules/recovery"
)

View file

@ -1,18 +1,6 @@
// Copyright 2015 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
// Copyright 2015 Jeffrey Wilcke, Felix Lange, Gustav Simonsson. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
// secp256k1_context_create_sign_verify creates a context for signing and signature verification.
static secp256k1_context* secp256k1_context_create_sign_verify() {

View file

@ -0,0 +1,8 @@
//go:build dummy
// +build dummy
// Package c contains only a C file.
//
// This Go file is part of a workaround for `go mod vendor`.
// Please see the file crypto/secp256k1/dummy.go for more information.
package contrib

View file

@ -0,0 +1,8 @@
//go:build dummy
// +build dummy
// Package c contains only a C file.
//
// This Go file is part of a workaround for `go mod vendor`.
// Please see the file crypto/secp256k1/dummy.go for more information.
package libsecp256k1

View file

@ -0,0 +1,8 @@
//go:build dummy
// +build dummy
// Package c contains only a C file.
//
// This Go file is part of a workaround for `go mod vendor`.
// Please see the file crypto/secp256k1/dummy.go for more information.
package include

View file

@ -11,7 +11,7 @@ Note:
- To avoid unnecessary loads and make use of available registers, two
'passes' have every time been interleaved, with the odd passes accumulating c' and d'
which will be added to c and d respectively in the the even passes
which will be added to c and d respectively in the even passes
*/
@ -23,7 +23,7 @@ Note:
.eabi_attribute 10, 0 @ Tag_FP_arch = none
.eabi_attribute 24, 1 @ Tag_ABI_align_needed = 8-byte
.eabi_attribute 25, 1 @ Tag_ABI_align_preserved = 8-byte, except leaf SP
.eabi_attribute 30, 2 @ Tag_ABI_optimization_goals = Agressive Speed
.eabi_attribute 30, 2 @ Tag_ABI_optimization_goals = Aggressive Speed
.eabi_attribute 34, 1 @ Tag_CPU_unaligned_access = v6
.text

View file

@ -0,0 +1,8 @@
//go:build dummy
// +build dummy
// Package c contains only a C file.
//
// This Go file is part of a workaround for `go mod vendor`.
// Please see the file crypto/secp256k1/dummy.go for more information.
package src

View file

@ -0,0 +1,8 @@
//go:build dummy
// +build dummy
// Package c contains only a C file.
//
// This Go file is part of a workaround for `go mod vendor`.
// Please see the file crypto/secp256k1/dummy.go for more information.
package module

View file

@ -0,0 +1,8 @@
//go:build dummy
// +build dummy
// Package c contains only a C file.
//
// This Go file is part of a workaround for `go mod vendor`.
// Please see the file crypto/secp256k1/dummy.go for more information.
package ecdh

View file

@ -0,0 +1,8 @@
//go:build dummy
// +build dummy
// Package c contains only a C file.
//
// This Go file is part of a workaround for `go mod vendor`.
// Please see the file crypto/secp256k1/dummy.go for more information.
package recovery

View file

@ -54,7 +54,7 @@ static void secp256k1_num_mul(secp256k1_num *r, const secp256k1_num *a, const se
even if r was negative. */
static void secp256k1_num_mod(secp256k1_num *r, const secp256k1_num *m);
/** Right-shift the passed number by bits bits. */
/** Right-shift the passed number by bits. */
static void secp256k1_num_shift(secp256k1_num *r, int bits);
/** Check whether a number is zero. */

View file

@ -26,7 +26,6 @@
} while(0)
static void default_illegal_callback_fn(const char* str, void* data) {
(void)data;
fprintf(stderr, "[libsecp256k1] illegal argument: %s\n", str);
abort();
}
@ -37,7 +36,6 @@ static const secp256k1_callback default_illegal_callback = {
};
static void default_error_callback_fn(const char* str, void* data) {
(void)data;
fprintf(stderr, "[libsecp256k1] internal consistency check failed: %s\n", str);
abort();
}

View file

@ -1,18 +1,9 @@
// Copyright 2015 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
// Copyright 2015 Jeffrey Wilcke, Felix Lange, Gustav Simonsson. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//go:build !gofuzz && cgo
// +build !gofuzz,cgo
package secp256k1

View file

@ -0,0 +1,57 @@
// Copyright 2015 Jeffrey Wilcke, Felix Lange, Gustav Simonsson. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//go:build !gofuzz && cgo
// +build !gofuzz,cgo
package secp256k1
import (
"math/big"
"unsafe"
)
/*
#include "libsecp256k1/include/secp256k1.h"
extern int secp256k1_ext_scalar_mul(const secp256k1_context* ctx, const unsigned char *point, const unsigned char *scalar);
*/
import "C"
func (BitCurve *BitCurve) ScalarMult(Bx, By *big.Int, scalar []byte) (*big.Int, *big.Int) {
// Ensure scalar is exactly 32 bytes. We pad always, even if
// scalar is 32 bytes long, to avoid a timing side channel.
if len(scalar) > 32 {
panic("can't handle scalars > 256 bits")
}
// NOTE: potential timing issue
padded := make([]byte, 32)
copy(padded[32-len(scalar):], scalar)
scalar = padded
// Do the multiplication in C, updating point.
point := make([]byte, 64)
readBits(Bx, point[:32])
readBits(By, point[32:])
pointPtr := (*C.uchar)(unsafe.Pointer(&point[0]))
scalarPtr := (*C.uchar)(unsafe.Pointer(&scalar[0]))
res := C.secp256k1_ext_scalar_mul(context, pointPtr, scalarPtr)
// Unpack the result and clear temporaries.
x := new(big.Int).SetBytes(point[:32])
y := new(big.Int).SetBytes(point[32:])
for i := range point {
point[i] = 0
}
for i := range padded {
scalar[i] = 0
}
if res != 1 {
return nil, nil
}
return x, y
}

View file

@ -0,0 +1,14 @@
// Copyright 2015 Jeffrey Wilcke, Felix Lange, Gustav Simonsson. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//go:build gofuzz || !cgo
// +build gofuzz !cgo
package secp256k1
import "math/big"
func (BitCurve *BitCurve) ScalarMult(Bx, By *big.Int, scalar []byte) (*big.Int, *big.Int) {
panic("ScalarMult is not available when secp256k1 is built without cgo")
}

View file

@ -1,18 +1,9 @@
// Copyright 2015 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
// Copyright 2015 Jeffrey Wilcke, Felix Lange, Gustav Simonsson. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//go:build !gofuzz && cgo
// +build !gofuzz,cgo
// Package secp256k1 wraps the bitcoin secp256k1 C library.
package secp256k1
@ -20,12 +11,24 @@ package secp256k1
/*
#cgo CFLAGS: -I./libsecp256k1
#cgo CFLAGS: -I./libsecp256k1/src/
#ifdef __SIZEOF_INT128__
# define HAVE___INT128
# define USE_FIELD_5X52
# define USE_SCALAR_4X64
#else
# define USE_FIELD_10X26
# define USE_SCALAR_8X32
#endif
#ifndef NDEBUG
# define NDEBUG
#endif
#define USE_ENDOMORPHISM
#define USE_NUM_NONE
#define USE_FIELD_10X26
#define USE_FIELD_INV_BUILTIN
#define USE_SCALAR_8X32
#define USE_SCALAR_INV_BUILTIN
#define NDEBUG
#include "./libsecp256k1/src/secp256k1.c"
#include "./libsecp256k1/src/modules/recovery/main_impl.h"
#include "ext.h"
@ -98,7 +101,7 @@ func Sign(msg []byte, seckey []byte) ([]byte, error) {
return sig, nil
}
// RecoverPubkey returns the the public key of the signer.
// RecoverPubkey returns the public key of the signer.
// msg must be the 32-byte hash of the message to be signed.
// sig must be a 65-byte compact ECDSA signature containing the
// recovery id as the last element.

View file

@ -1,18 +1,9 @@
// Copyright 2015 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
// Copyright 2015 Jeffrey Wilcke, Felix Lange, Gustav Simonsson. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//go:build !gofuzz && cgo
// +build !gofuzz,cgo
package secp256k1
@ -22,10 +13,8 @@ import (
"crypto/elliptic"
"crypto/rand"
"encoding/hex"
"io"
"testing"
"github.com/XinFinOrg/XDPoSChain/common/math"
"github.com/XinFinOrg/XDPoSChain/crypto/randentropy"
)
const TestCount = 1000
@ -36,11 +25,24 @@ func generateKeyPair() (pubkey, privkey []byte) {
panic(err)
}
pubkey = elliptic.Marshal(S256(), key.X, key.Y)
return pubkey, math.PaddedBigBytes(key.D, 32)
privkey = make([]byte, 32)
blob := key.D.Bytes()
copy(privkey[32-len(blob):], blob)
return pubkey, privkey
}
func csprngEntropy(n int) []byte {
buf := make([]byte, n)
if _, err := io.ReadFull(rand.Reader, buf); err != nil {
panic("reading from crypto/rand failed: " + err.Error())
}
return buf
}
func randSig() []byte {
sig := randentropy.GetEntropyCSPRNG(65)
sig := csprngEntropy(65)
sig[32] &= 0x70
sig[64] %= 4
return sig
@ -49,7 +51,7 @@ func randSig() []byte {
// tests for malleability
// highest bit of signature ECDSA s value must be 0, in the 33th byte
func compactSigCheck(t *testing.T, sig []byte) {
var b int = int(sig[32])
var b = int(sig[32])
if b < 0 {
t.Errorf("highest bit is negative: %d", b)
}
@ -63,7 +65,7 @@ func compactSigCheck(t *testing.T, sig []byte) {
func TestSignatureValidity(t *testing.T) {
pubkey, seckey := generateKeyPair()
msg := randentropy.GetEntropyCSPRNG(32)
msg := csprngEntropy(32)
sig, err := Sign(msg, seckey)
if err != nil {
t.Errorf("signature error: %s", err)
@ -86,7 +88,7 @@ func TestSignatureValidity(t *testing.T) {
func TestInvalidRecoveryID(t *testing.T) {
_, seckey := generateKeyPair()
msg := randentropy.GetEntropyCSPRNG(32)
msg := csprngEntropy(32)
sig, _ := Sign(msg, seckey)
sig[64] = 99
_, err := RecoverPubkey(msg, sig)
@ -97,7 +99,7 @@ func TestInvalidRecoveryID(t *testing.T) {
func TestSignAndRecover(t *testing.T) {
pubkey1, seckey := generateKeyPair()
msg := randentropy.GetEntropyCSPRNG(32)
msg := csprngEntropy(32)
sig, err := Sign(msg, seckey)
if err != nil {
t.Errorf("signature error: %s", err)
@ -148,7 +150,7 @@ func TestRandomMessagesWithRandomKeys(t *testing.T) {
func signAndRecoverWithRandomMessages(t *testing.T, keys func() ([]byte, []byte)) {
for i := 0; i < TestCount; i++ {
pubkey1, seckey := keys()
msg := randentropy.GetEntropyCSPRNG(32)
msg := csprngEntropy(32)
sig, err := Sign(msg, seckey)
if err != nil {
t.Fatalf("signature error: %s", err)
@ -176,7 +178,7 @@ func signAndRecoverWithRandomMessages(t *testing.T, keys func() ([]byte, []byte)
func TestRecoveryOfRandomSignature(t *testing.T) {
pubkey1, _ := generateKeyPair()
msg := randentropy.GetEntropyCSPRNG(32)
msg := csprngEntropy(32)
for i := 0; i < TestCount; i++ {
// recovery can sometimes work, but if so should always give wrong pubkey
@ -189,11 +191,11 @@ func TestRecoveryOfRandomSignature(t *testing.T) {
func TestRandomMessagesAgainstValidSig(t *testing.T) {
pubkey1, seckey := generateKeyPair()
msg := randentropy.GetEntropyCSPRNG(32)
msg := csprngEntropy(32)
sig, _ := Sign(msg, seckey)
for i := 0; i < TestCount; i++ {
msg = randentropy.GetEntropyCSPRNG(32)
msg = csprngEntropy(32)
pubkey2, _ := RecoverPubkey(msg, sig)
// recovery can sometimes work, but if so should always give wrong pubkey
if bytes.Equal(pubkey1, pubkey2) {
@ -219,7 +221,7 @@ func TestRecoverSanity(t *testing.T) {
func BenchmarkSign(b *testing.B) {
_, seckey := generateKeyPair()
msg := randentropy.GetEntropyCSPRNG(32)
msg := csprngEntropy(32)
b.ResetTimer()
for i := 0; i < b.N; i++ {
@ -228,7 +230,7 @@ func BenchmarkSign(b *testing.B) {
}
func BenchmarkRecover(b *testing.B) {
msg := randentropy.GetEntropyCSPRNG(32)
msg := csprngEntropy(32)
_, seckey := generateKeyPair()
sig, _ := Sign(msg, seckey)
b.ResetTimer()

View file

@ -94,13 +94,14 @@ type Service struct {
// websocket.
//
// From Gorilla websocket docs:
// Connections support one concurrent reader and one concurrent writer.
// Applications are responsible for ensuring that no more than one goroutine calls the write methods
// - NextWriter, SetWriteDeadline, WriteMessage, WriteJSON, EnableWriteCompression, SetCompressionLevel
// concurrently and that no more than one goroutine calls the read methods
// - NextReader, SetReadDeadline, ReadMessage, ReadJSON, SetPongHandler, SetPingHandler
// concurrently.
// The Close and WriteControl methods can be called concurrently with all other methods.
//
// Connections support one concurrent reader and one concurrent writer.
// Applications are responsible for ensuring that no more than one goroutine calls the write methods
// - NextWriter, SetWriteDeadline, WriteMessage, WriteJSON, EnableWriteCompression, SetCompressionLevel
// concurrently and that no more than one goroutine calls the read methods
// - NextReader, SetReadDeadline, ReadMessage, ReadJSON, SetPongHandler, SetPingHandler
// concurrently.
// The Close and WriteControl methods can be called concurrently with all other methods.
type connWrapper struct {
conn *websocket.Conn
@ -674,7 +675,10 @@ func (s *Service) assembleBlockStats(block *types.Block) *blockStats {
txs = []txStats{}
}
// Assemble and return the block stats
author, _ := s.engine.Author(header)
author, err := s.engine.Author(header)
if err != nil {
log.Error("Failed to retrieve block author", "err", err, "number", header.Number, "hash", header.Hash())
}
return &blockStats{
Number: header.Number,

View file

@ -106,7 +106,7 @@ var Flags = []cli.Flag{
//blockprofilerateFlag,
cpuprofileFlag,
//traceFlag,
periodicProfilingFlag,
//periodicProfilingFlag,
debugDataDirFlag,
}

View file

@ -1251,7 +1251,7 @@ func (s *PublicBlockChainAPI) EstimateGas(ctx context.Context, args CallArgs, bl
res, _, failed, err, vmErr := s.doCall(ctx, args, rpc.LatestBlockNumber, vm.Config{}, 0)
if err != nil {
if errors.Is(err, core.ErrIntrinsicGas) {
if errors.Is(err, vm.ErrOutOfGas) || errors.Is(err, core.ErrIntrinsicGas) {
return false, nil, nil, nil // Special case, raise gas limit
}
return false, nil, err, nil // Bail out
@ -1262,6 +1262,25 @@ func (s *PublicBlockChainAPI) EstimateGas(ctx context.Context, args CallArgs, bl
return true, nil, nil, nil
}
// If the transaction is a plain value transfer, short circuit estimation and
// directly try 21000. Returning 21000 without any execution is dangerous as
// some tx field combos might bump the price up even for plain transfers (e.g.
// unused access list items). Ever so slightly wasteful, but safer overall.
if len(args.Data) == 0 && args.To != nil {
statedb, _, err := s.b.StateAndHeaderByNumber(ctx, rpc.LatestBlockNumber)
if statedb == nil || err != nil {
return 0, err
}
if statedb.GetCodeSize(*args.To) == 0 {
ok, _, err, _ := executable(params.TxGas)
if ok && err == nil {
return hexutil.Uint64(params.TxGas), nil
}
}
}
// Execute the binary search and hone in on an executable gas limit
for lo+1 < hi {
mid := (hi + lo) / 2

View file

@ -388,7 +388,7 @@ func (v *V2) UpdateConfig(round uint64) {
}
}
// update to current config
log.Warn("[updateV2Config] Update config", "index", index, "round", round, "SwitchRound", v.AllConfigs[index].SwitchRound)
log.Info("[updateV2Config] Update config", "index", index, "round", round, "SwitchRound", v.AllConfigs[index].SwitchRound)
v.CurrentConfig = v.AllConfigs[index]
}

View file

@ -23,7 +23,7 @@ import (
const (
VersionMajor = 2 // Major version component of the current release
VersionMinor = 0 // Minor version component of the current release
VersionPatch = 1 // Patch version component of the current release
VersionPatch = 2 // Patch version component of the current release
VersionMeta = "beta1" // Version metadata to append to the version string
)