Skip to content

Commit

Permalink
Merge pull request #1950 from PlatONnetwork/feature/delegating-lockup
Browse files Browse the repository at this point in the history
Feature/delegating lockup
  • Loading branch information
benbaley authored Oct 12, 2022
2 parents dd18bfd + 637e004 commit 8ddcea2
Show file tree
Hide file tree
Showing 366 changed files with 313,545 additions and 7,972 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/unit_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ env:
jobs:
test:
name: Build
runs-on: self-hosted
runs-on: ubuntu-18.04
steps:

- name: Set up Go 1.x
Expand Down
45 changes: 45 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# This file configures github.com/golangci/golangci-lint.

run:
timeout: 2m
tests: true
# default is true. Enables skipping of directories:
# vendor$, third_party$, testdata$, examples$, Godeps$, builtin$
skip-dirs-use-default: true

linters:
disable-all: true
enable:
- deadcode
- goconst
- goimports
- gosimple
- govet
- ineffassign
- misspell
# - staticcheck
- unconvert
# - unused
- varcheck

linters-settings:
gofmt:
simplify: true
goconst:
min-len: 3 # minimum length of string constant
min-occurrences: 6 # minimum number of occurrences

issues:
exclude-rules:
- path: crypto/blake2b/
linters:
- deadcode
- path: crypto/bn256/cloudflare
linters:
- deadcode
- path: p2p/discv5/
linters:
- deadcode
- path: core/vm/instructions_test.go
linters:
- goconst
1 change: 0 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ lint: ## Run linters.

clean:
./build/clean_deps.sh
./build/clean_go_build_cache.sh
env GO111MODULE=on go clean -cache
rm -fr build/_workspace/pkg/ $(GOBIN)/*

Expand Down
6 changes: 3 additions & 3 deletions accounts/abi/bind/backends/simulated.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,13 @@ type SimulatedBackend struct {
func NewSimulatedBackendWithDatabase(database ethdb.Database, alloc core.GenesisAlloc, gasLimit uint64) *SimulatedBackend {
genesis := core.Genesis{Config: params.AllEthashProtocolChanges, GasLimit: gasLimit, Alloc: alloc}
genesis.MustCommit(database)
blockchain, _ := core.NewBlockChain(database, nil, genesis.Config, consensus.NewFakerWithDataBase(database), vm.Config{}, nil)
blockchain, _ := core.NewBlockChain(database, nil, genesis.Config, consensus.NewFakerWithDataBase(database), vm.Config{}, nil, nil)

backend := &SimulatedBackend{
database: database,
blockchain: blockchain,
config: genesis.Config,
events: filters.NewEventSystem(new(event.TypeMux), &filterBackend{database, blockchain}, false),
events: filters.NewEventSystem(&filterBackend{database, blockchain}, false),
}
backend.rollback()
return backend
Expand Down Expand Up @@ -117,7 +117,7 @@ func (b *SimulatedBackend) Commit() {
panic(err) // This cannot happen unless the simulator is wrong, fail in that case
}
stateDB, _ := b.blockchain.State()
b.blockchain.WriteBlockWithState(b.pendingBlock, b.pendingReceipts, stateDB)
b.blockchain.WriteBlockWithState(b.pendingBlock, b.pendingReceipts, nil, stateDB, true)
b.rollback()
}

Expand Down
1 change: 1 addition & 0 deletions accounts/abi/numbers.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ var (
)

// U256 converts a big Int into a 256bit EVM number.
// This operation is destructive.
func U256(n *big.Int) []byte {
return math.PaddedBigBytes(math.U256(n), 32)
}
11 changes: 2 additions & 9 deletions accounts/abi/reflect.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,15 +123,8 @@ func set(dst, src reflect.Value) error {
func setSlice(dst, src reflect.Value) error {
slice := reflect.MakeSlice(dst.Type(), src.Len(), src.Len())
for i := 0; i < src.Len(); i++ {
if src.Index(i).Kind() == reflect.Struct {
if err := set(slice.Index(i), src.Index(i)); err != nil {
return err
}
} else {
// e.g. [][32]uint8 to []common.Hash
if err := set(slice.Index(i), src.Index(i)); err != nil {
return err
}
if err := set(slice.Index(i), src.Index(i)); err != nil {
return err
}
}
if dst.CanSet() {
Expand Down
6 changes: 5 additions & 1 deletion accounts/accounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,13 @@ type Wallet interface {
// opposed to decending into a child path to allow discovering accounts starting
// from non zero components.
//
// Some hardware wallets switched derivation paths through their evolution, so
// this method supports providing multiple bases to discover old user accounts
// too. Only the last base will be used to derive the next empty account.
//
// You can disable automatic account discovery by calling SelfDerive with a nil
// chain state reader.
SelfDerive(base DerivationPath, chain ethereum.ChainStateReader)
SelfDerive(bases []DerivationPath, chain ethereum.ChainStateReader)

// SignHash requests the wallet to sign the given hash.
//
Expand Down
2 changes: 1 addition & 1 deletion accounts/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ var ErrNotSupported = errors.New("not supported")

// ErrInvalidPassphrase is returned when a decryption operation receives a bad
// passphrase.
var ErrInvalidPassphrase = errors.New("invalid passphrase")
var ErrInvalidPassphrase = errors.New("invalid password")

// ErrWalletAlreadyOpen is returned if a wallet is attempted to be opened the
// second time.
Expand Down
12 changes: 6 additions & 6 deletions accounts/hd.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ import (
var DefaultRootDerivationPath = DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 0}

// DefaultBaseDerivationPath is the base path from which custom derivation endpoints
// are incremented. As such, the first account will be at m/44'/60'/0'/0, the second
// at m/44'/60'/0'/1, etc.
// are incremented. As such, the first account will be at m/44'/60'/0'/0/0, the second
// at m/44'/60'/0'/0/1, etc.
var DefaultBaseDerivationPath = DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 0, 0}

// DefaultLedgerBaseDerivationPath is the base path from which custom derivation endpoints
// are incremented. As such, the first account will be at m/44'/60'/0'/0, the second
// at m/44'/60'/0'/1, etc.
var DefaultLedgerBaseDerivationPath = DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 0}
// LegacyLedgerBaseDerivationPath is the legacy base path from which custom derivation
// endpoints are incremented. As such, the first account will be at m/44'/60'/0'/0, the
// second at m/44'/60'/0'/1, etc.
var LegacyLedgerBaseDerivationPath = DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 0}

// DerivationPath represents the computer friendly version of a hierarchical
// deterministic wallet account derivaion path.
Expand Down
15 changes: 11 additions & 4 deletions accounts/keystore/keystore.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import (
"crypto/ecdsa"
crand "crypto/rand"
"errors"
"fmt"
"math/big"
"os"
"path/filepath"
Expand All @@ -43,7 +42,7 @@ import (
var (
ErrLocked = accounts.NewAuthNeededError("password or unlock")
ErrNoMatch = errors.New("no key for given address or file")
ErrDecrypt = errors.New("could not decrypt key with given passphrase")
ErrDecrypt = errors.New("could not decrypt key with given password")
)

// KeyStoreType is the reflect type of a keystore backend.
Expand All @@ -67,7 +66,8 @@ type KeyStore struct {
updateScope event.SubscriptionScope // Subscription scope tracking current live listeners
updating bool // Whether the event notification loop is running

mu sync.RWMutex
mu sync.RWMutex
importMu sync.Mutex // Import Mutex locks the import to prevent two insertions from racing
}

type unlocked struct {
Expand Down Expand Up @@ -437,14 +437,21 @@ func (ks *KeyStore) Import(keyJSON []byte, passphrase, newPassphrase string) (ac
if err != nil {
return accounts.Account{}, err
}
ks.importMu.Lock()
defer ks.importMu.Unlock()
if ks.cache.hasAddress(key.Address) {
return accounts.Account{}, errors.New("account already exists")
}
return ks.importKey(key, newPassphrase)
}

// ImportECDSA stores the given key into the key directory, encrypting it with the passphrase.
func (ks *KeyStore) ImportECDSA(priv *ecdsa.PrivateKey, passphrase string) (accounts.Account, error) {
key := newKeyFromECDSA(priv)
ks.importMu.Lock()
defer ks.importMu.Unlock()
if ks.cache.hasAddress(key.Address) {
return accounts.Account{}, fmt.Errorf("account already exists")
return accounts.Account{}, errors.New("account already exists")
}
return ks.importKey(key, passphrase)
}
Expand Down
85 changes: 85 additions & 0 deletions accounts/keystore/keystore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,15 @@
package keystore

import (
"github.com/PlatONnetwork/PlatON-Go/crypto"
"io/ioutil"
"math/rand"
"os"
"runtime"
"sort"
"strings"
"sync"
"sync/atomic"
"testing"
"time"

Expand Down Expand Up @@ -338,6 +341,88 @@ func TestWalletNotifications(t *testing.T) {
checkEvents(t, wantEvents, events)
}

// TestImportExport tests the import functionality of a keystore.
func TestImportECDSA(t *testing.T) {
dir, ks := tmpKeyStore(t, true)
defer os.RemoveAll(dir)
key, err := crypto.GenerateKey()
if err != nil {
t.Fatalf("failed to generate key: %v", key)
}
if _, err = ks.ImportECDSA(key, "old"); err != nil {
t.Errorf("importing failed: %v", err)
}
if _, err = ks.ImportECDSA(key, "old"); err == nil {
t.Errorf("importing same key twice succeeded")
}
if _, err = ks.ImportECDSA(key, "new"); err == nil {
t.Errorf("importing same key twice succeeded")
}
}

// TestImportECDSA tests the import and export functionality of a keystore.
func TestImportExport(t *testing.T) {
dir, ks := tmpKeyStore(t, true)
defer os.RemoveAll(dir)
acc, err := ks.NewAccount("old")
if err != nil {
t.Fatalf("failed to create account: %v", acc)
}
json, err := ks.Export(acc, "old", "new")
if err != nil {
t.Fatalf("failed to export account: %v", acc)
}
dir2, ks2 := tmpKeyStore(t, true)
defer os.RemoveAll(dir2)
if _, err = ks2.Import(json, "old", "old"); err == nil {
t.Errorf("importing with invalid password succeeded")
}
acc2, err := ks2.Import(json, "new", "new")
if err != nil {
t.Errorf("importing failed: %v", err)
}
if acc.Address != acc2.Address {
t.Error("imported account does not match exported account")
}
if _, err = ks2.Import(json, "new", "new"); err == nil {
t.Errorf("importing a key twice succeeded")
}

}

// TestImportRace tests the keystore on races.
// This test should fail under -race if importing races.
func TestImportRace(t *testing.T) {
dir, ks := tmpKeyStore(t, true)
defer os.RemoveAll(dir)
acc, err := ks.NewAccount("old")
if err != nil {
t.Fatalf("failed to create account: %v", acc)
}
json, err := ks.Export(acc, "old", "new")
if err != nil {
t.Fatalf("failed to export account: %v", acc)
}
dir2, ks2 := tmpKeyStore(t, true)
defer os.RemoveAll(dir2)
var atom uint32
var wg sync.WaitGroup
wg.Add(2)
for i := 0; i < 2; i++ {
go func() {
defer wg.Done()
if _, err := ks2.Import(json, "new", "new"); err != nil {
atomic.AddUint32(&atom, 1)
}

}()
}
wg.Wait()
if atom != 1 {
t.Errorf("Import is racy")
}
}

// checkAccounts checks that all known live accounts are present in the wallet list.
func checkAccounts(t *testing.T, live map[common.Address]accounts.Account, wallets []accounts.Wallet) {
if len(live) != len(wallets) {
Expand Down
15 changes: 8 additions & 7 deletions accounts/keystore/passphrase.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ import (
"os"
"path/filepath"

"github.com/pborman/uuid"
"golang.org/x/crypto/pbkdf2"
"golang.org/x/crypto/scrypt"
"github.com/PlatONnetwork/PlatON-Go/accounts"
"github.com/PlatONnetwork/PlatON-Go/common"
"github.com/PlatONnetwork/PlatON-Go/common/math"
"github.com/PlatONnetwork/PlatON-Go/crypto"
"github.com/pborman/uuid"
"golang.org/x/crypto/pbkdf2"
"golang.org/x/crypto/scrypt"
)

const (
Expand Down Expand Up @@ -123,6 +123,7 @@ func (ks keyStorePassphrase) StoreKey(filename string, key *Key, auth string) er
"Please file a ticket at:\n\n" +
"https://github.com/ethereum/go-ethereum/issues." +
"The error was : %s"
//lint:ignore ST1005 This is a message for the user
return fmt.Errorf(msg, tmpName, err)
}
}
Expand Down Expand Up @@ -230,11 +231,11 @@ func DecryptKey(keyjson []byte, auth string) (*Key, error) {

func decryptKeyV3(keyProtected *encryptedKeyJSONV3, auth string) (keyBytes []byte, keyId []byte, err error) {
if keyProtected.Version != version {
return nil, nil, fmt.Errorf("Version not supported: %v", keyProtected.Version)
return nil, nil, fmt.Errorf("version not supported: %v", keyProtected.Version)
}

if keyProtected.Crypto.Cipher != "aes-128-ctr" {
return nil, nil, fmt.Errorf("Cipher not supported: %v", keyProtected.Crypto.Cipher)
return nil, nil, fmt.Errorf("cipher not supported: %v", keyProtected.Crypto.Cipher)
}

keyId = uuid.Parse(keyProtected.Id)
Expand Down Expand Up @@ -322,13 +323,13 @@ func getKDFKey(cryptoJSON cryptoJSON, auth string) ([]byte, error) {
c := ensureInt(cryptoJSON.KDFParams["c"])
prf := cryptoJSON.KDFParams["prf"].(string)
if prf != "hmac-sha256" {
return nil, fmt.Errorf("Unsupported PBKDF2 PRF: %s", prf)
return nil, fmt.Errorf("unsupported PBKDF2 PRF: %s", prf)
}
key := pbkdf2.Key(authArray, salt, c, dkLen, sha256.New)
return key, nil
}

return nil, fmt.Errorf("Unsupported KDF: %s", cryptoJSON.KDF)
return nil, fmt.Errorf("unsupported KDF: %s", cryptoJSON.KDF)
}

// TODO: can we do without this when unmarshalling dynamic JSON?
Expand Down
2 changes: 1 addition & 1 deletion accounts/keystore/plain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ func TestKeyStorePassphraseDecryptionFail(t *testing.T) {
t.Fatal(err)
}
if _, err = ks.GetKey(k1.Address, account.URL.Path, "bar"); err != ErrDecrypt {
t.Fatalf("wrong error for invalid passphrase\ngot %q\nwant %q", err, ErrDecrypt)
t.Fatalf("wrong error for invalid password\ngot %q\nwant %q", err, ErrDecrypt)
}
}

Expand Down
2 changes: 1 addition & 1 deletion accounts/keystore/testdata/keystore/README
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
This directory contains accounts for testing.
The passphrase that unlocks them is "foobar".
The password that unlocks them is "foobar".

The "good" key files which are supposed to be loadable are:

Expand Down
3 changes: 2 additions & 1 deletion accounts/keystore/wallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ func (w *keystoreWallet) Derive(path accounts.DerivationPath, pin bool) (account

// SelfDerive implements accounts.Wallet, but is a noop for plain wallets since
// there is no notion of hierarchical account derivation for plain keystore accounts.
func (w *keystoreWallet) SelfDerive(base accounts.DerivationPath, chain ethereum.ChainStateReader) {}
func (w *keystoreWallet) SelfDerive(bases []accounts.DerivationPath, chain ethereum.ChainStateReader) {
}

// SignHash implements accounts.Wallet, attempting to sign the given hash with
// the given account. If the wallet does not wrap this particular account, an
Expand Down
Loading

0 comments on commit 8ddcea2

Please sign in to comment.