mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2024-12-22 03:30:37 +00:00
post-rebase fixups
This commit is contained in:
parent
2df2531eaf
commit
93f6c4c01a
@ -30,6 +30,7 @@ import (
|
||||
"github.com/ledgerwatch/turbo-geth/accounts/abi"
|
||||
"github.com/ledgerwatch/turbo-geth/accounts/abi/bind"
|
||||
"github.com/ledgerwatch/turbo-geth/common"
|
||||
"github.com/ledgerwatch/turbo-geth/common/hexutil"
|
||||
"github.com/ledgerwatch/turbo-geth/common/math"
|
||||
"github.com/ledgerwatch/turbo-geth/common/u256"
|
||||
"github.com/ledgerwatch/turbo-geth/consensus"
|
||||
@ -199,10 +200,6 @@ func (b *SimulatedBackend) stateByBlockNumber(ctx context.Context, blockNumber *
|
||||
if blockNumber == nil || blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) == 0 {
|
||||
return state.New(state.NewDbState(b.kv, b.blockchain.CurrentBlock().NumberU64())), nil
|
||||
}
|
||||
block, err := b.blockByNumberNoLock(ctx, blockNumber)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return state.New(state.NewDbState(b.kv, uint64(blockNumber.Int64()))), nil
|
||||
}
|
||||
|
||||
@ -312,7 +309,7 @@ func (b *SimulatedBackend) BlockByNumber(ctx context.Context, number *big.Int) (
|
||||
|
||||
// blockByNumberNoLock retrieves a block from the database by number, caching it
|
||||
// (associated with its hash) if found without Lock.
|
||||
func (b *SimulatedBackend) blockByNumberNoLock(ctx context.Context, number *big.Int) (*types.Block, error) {
|
||||
func (b *SimulatedBackend) blockByNumberNoLock(_ context.Context, number *big.Int) (*types.Block, error) {
|
||||
if number == nil || number.Cmp(b.pendingBlock.Number()) == 0 {
|
||||
return b.blockchain.CurrentBlock(), nil
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ func simTestBackend(testAddr common.Address) *SimulatedBackend {
|
||||
|
||||
func TestNewSimulatedBackend(t *testing.T) {
|
||||
testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
|
||||
expectedBal := big.NewInt(10000000000)
|
||||
expectedBal := uint256.NewInt().SetUint64(10000000000)
|
||||
sim := simTestBackend(testAddr)
|
||||
defer sim.Close()
|
||||
|
||||
|
@ -115,7 +115,7 @@ func setSlice(dst, src reflect.Value) error {
|
||||
dst.Set(slice)
|
||||
return nil
|
||||
}
|
||||
return errors.New("Cannot set slice, destination not settable")
|
||||
return errors.New("cannot set slice, destination not settable")
|
||||
}
|
||||
|
||||
func setArray(dst, src reflect.Value) error {
|
||||
@ -133,7 +133,7 @@ func setArray(dst, src reflect.Value) error {
|
||||
dst.Set(array)
|
||||
return nil
|
||||
}
|
||||
return errors.New("Cannot set array, destination not settable")
|
||||
return errors.New("cannot set array, destination not settable")
|
||||
}
|
||||
|
||||
func setStruct(dst, src reflect.Value) error {
|
||||
@ -141,7 +141,7 @@ func setStruct(dst, src reflect.Value) error {
|
||||
srcField := src.Field(i)
|
||||
dstField := dst.Field(i)
|
||||
if !dstField.IsValid() || !srcField.IsValid() {
|
||||
return fmt.Errorf("Could not find src field: %v value: %v in destination", srcField.Type().Name(), srcField)
|
||||
return fmt.Errorf("could not find src field: %v value: %v in destination", srcField.Type().Name(), srcField)
|
||||
}
|
||||
if err := set(dstField, srcField); err != nil {
|
||||
return err
|
||||
|
@ -39,7 +39,6 @@ import (
|
||||
"github.com/ledgerwatch/turbo-geth/eth/downloader"
|
||||
"github.com/ledgerwatch/turbo-geth/ethclient"
|
||||
"github.com/ledgerwatch/turbo-geth/internal/debug"
|
||||
"github.com/ethereum/go-ethereum/les"
|
||||
"github.com/ledgerwatch/turbo-geth/log"
|
||||
"github.com/ledgerwatch/turbo-geth/metrics"
|
||||
"github.com/ledgerwatch/turbo-geth/node"
|
||||
@ -324,7 +323,9 @@ func prepare(ctx *cli.Context) {
|
||||
allowance := int(mem.Total / 1024 / 1024 / 3)
|
||||
if cache := ctx.GlobalInt(utils.CacheFlag.Name); cache > allowance {
|
||||
log.Warn("Sanitizing cache to Go's GC limits", "provided", cache, "updated", allowance)
|
||||
ctx.GlobalSet(utils.CacheFlag.Name, strconv.Itoa(allowance))
|
||||
if err = ctx.GlobalSet(utils.CacheFlag.Name, strconv.Itoa(allowance)); err != nil {
|
||||
log.Error("Error while sanitizing cache to Go's GC limits", "err", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Ensure Go's GC ignores the database cache for trigger percentage
|
||||
|
@ -43,7 +43,7 @@ func NewDepTracer() *DepTracer {
|
||||
func (dt *DepTracer) CaptureStart(depth int, from common.Address, to common.Address, call bool, input []byte, gas uint64, value *big.Int) error {
|
||||
return nil
|
||||
}
|
||||
func (dt *DepTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, contract *vm.Contract, depth int, err error) error {
|
||||
func (dt *DepTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, _ *stack.ReturnStack, contract *vm.Contract, depth int, err error) error {
|
||||
if op == vm.SSTORE {
|
||||
addr := contract.Address()
|
||||
if stack.Len() == 0 {
|
||||
@ -73,7 +73,7 @@ func (dt *DepTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cos
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (dt *DepTracer) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, contract *vm.Contract, depth int, err error) error {
|
||||
func (dt *DepTracer) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, _ *stack.ReturnStack, contract *vm.Contract, depth int, err error) error {
|
||||
dt.accountsWriteSetFrame = make(map[common.Address]struct{})
|
||||
dt.storageWriteSetFrame = make(map[common.Address]map[common.Hash]struct{})
|
||||
return nil
|
||||
|
@ -42,10 +42,10 @@ func NewAccountsTracer() *AccountsTracer {
|
||||
func (at *AccountsTracer) CaptureStart(depth int, from common.Address, to common.Address, call bool, input []byte, gas uint64, value *big.Int) error {
|
||||
return nil
|
||||
}
|
||||
func (at *AccountsTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, contract *vm.Contract, depth int, err error) error {
|
||||
func (at *AccountsTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, _ *stack.ReturnStack, contract *vm.Contract, depth int, err error) error {
|
||||
return nil
|
||||
}
|
||||
func (at *AccountsTracer) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, contract *vm.Contract, depth int, err error) error {
|
||||
func (at *AccountsTracer) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, _ *stack.ReturnStack, contract *vm.Contract, depth int, err error) error {
|
||||
return nil
|
||||
}
|
||||
func (at *AccountsTracer) CaptureEnd(depth int, output []byte, gasUsed uint64, t time.Duration, err error) error {
|
||||
|
@ -43,7 +43,7 @@ func NewStorageTracer() *StorageTracer {
|
||||
func (st *StorageTracer) CaptureStart(depth int, from common.Address, to common.Address, call bool, input []byte, gas uint64, value *big.Int) error {
|
||||
return nil
|
||||
}
|
||||
func (st *StorageTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, contract *vm.Contract, depth int, err error) error {
|
||||
func (st *StorageTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, _ *stack.ReturnStack, contract *vm.Contract, depth int, err error) error {
|
||||
if op == vm.SSTORE {
|
||||
addr := contract.Address()
|
||||
if stack.Len() == 0 {
|
||||
@ -83,7 +83,7 @@ func (st *StorageTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (st *StorageTracer) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, contract *vm.Contract, depth int, err error) error {
|
||||
func (st *StorageTracer) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, _ *stack.ReturnStack, contract *vm.Contract, depth int, err error) error {
|
||||
return nil
|
||||
}
|
||||
func (st *StorageTracer) CaptureEnd(depth int, output []byte, gasUsed uint64, t time.Duration, err error) error {
|
||||
|
@ -70,7 +70,7 @@ func (ct *CombTracer) ResetSets() {
|
||||
func (ct *CombTracer) CaptureStart(depth int, from common.Address, to common.Address, call bool, input []byte, gas uint64, value *big.Int) error {
|
||||
return nil
|
||||
}
|
||||
func (ct *CombTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, contract *vm.Contract, depth int, err error) error {
|
||||
func (ct *CombTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, _ *stack.ReturnStack, contract *vm.Contract, depth int, err error) error {
|
||||
if op == vm.SSTORE {
|
||||
addr := contract.Address()
|
||||
if stack.Len() == 0 {
|
||||
@ -120,7 +120,7 @@ func (ct *CombTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, co
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (ct *CombTracer) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, contract *vm.Contract, depth int, err error) error {
|
||||
func (ct *CombTracer) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, _ *stack.ReturnStack, contract *vm.Contract, depth int, err error) error {
|
||||
return nil
|
||||
}
|
||||
func (ct *CombTracer) CaptureEnd(depth int, output []byte, gasUsed uint64, t time.Duration, err error) error {
|
||||
|
@ -1340,10 +1340,10 @@ func NewCreationTracer(w io.Writer) CreationTracer {
|
||||
func (ct CreationTracer) CaptureStart(depth int, from common.Address, to common.Address, call bool, input []byte, gas uint64, value *big.Int) error {
|
||||
return nil
|
||||
}
|
||||
func (ct CreationTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, contract *vm.Contract, depth int, err error) error {
|
||||
func (ct CreationTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, _ *stack.ReturnStack, contract *vm.Contract, depth int, err error) error {
|
||||
return nil
|
||||
}
|
||||
func (ct CreationTracer) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, contract *vm.Contract, depth int, err error) error {
|
||||
func (ct CreationTracer) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, _ *stack.ReturnStack, contract *vm.Contract, depth int, err error) error {
|
||||
return nil
|
||||
}
|
||||
func (ct CreationTracer) CaptureEnd(depth int, output []byte, gasUsed uint64, t time.Duration, err error) error {
|
||||
|
@ -69,10 +69,10 @@ func (tt TokenTracer) CaptureStart(depth int, from common.Address, to common.Add
|
||||
tt.startMode[depth] = true
|
||||
return nil
|
||||
}
|
||||
func (tt TokenTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, contract *vm.Contract, depth int, err error) error {
|
||||
func (tt TokenTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, _ *stack.ReturnStack, contract *vm.Contract, depth int, err error) error {
|
||||
return nil
|
||||
}
|
||||
func (tt TokenTracer) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, contract *vm.Contract, depth int, err error) error {
|
||||
func (tt TokenTracer) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, _ *stack.ReturnStack, contract *vm.Contract, depth int, err error) error {
|
||||
return nil
|
||||
}
|
||||
func (tt TokenTracer) CaptureEnd(depth int, output []byte, gasUsed uint64, t time.Duration, err error) error {
|
||||
|
@ -95,7 +95,7 @@ func (tt *TxTracer) queryStorageAccess(account common.Address, storageKey common
|
||||
}
|
||||
}
|
||||
|
||||
func (tt *TxTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, contract *vm.Contract, depth int, err error) error {
|
||||
func (tt *TxTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, _ *stack.ReturnStack, contract *vm.Contract, depth int, err error) error {
|
||||
if tt.measureCreate && tt.measureDepth+1 == depth {
|
||||
tt.gasForCREATE += (tt.measureCurrentGas - gas)
|
||||
}
|
||||
@ -136,7 +136,7 @@ func (tt *TxTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (tt *TxTracer) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, contract *vm.Contract, depth int, err error) error {
|
||||
func (tt *TxTracer) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, _ *stack.ReturnStack, contract *vm.Contract, depth int, err error) error {
|
||||
return nil
|
||||
}
|
||||
func (tt *TxTracer) CaptureEnd(depth int, output []byte, gasUsed uint64, t time.Duration, err error) error {
|
||||
|
@ -15,7 +15,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/ledgerwatch/turbo-geth/cmd/utils"
|
||||
"github.com/ledgerwatch/turbo-geth/console"
|
||||
"github.com/ledgerwatch/turbo-geth/console/prompt"
|
||||
"github.com/ledgerwatch/turbo-geth/crypto"
|
||||
"github.com/ledgerwatch/turbo-geth/eth"
|
||||
"github.com/ledgerwatch/turbo-geth/internal/debug"
|
||||
@ -65,7 +65,7 @@ func init() {
|
||||
|
||||
app.After = func(ctx *cli.Context) error {
|
||||
debug.Exit()
|
||||
console.Stdin.Close() // Resets terminal mode.
|
||||
prompt.Stdin.Close() // Resets terminal mode.
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -1630,7 +1630,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {
|
||||
setDNSDiscoveryDefaults(cfg, params.GoerliGenesisHash)
|
||||
case ctx.GlobalBool(YoloV1Flag.Name):
|
||||
if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
|
||||
cfg.NetworkId = 133519467574833 // "yolov1"
|
||||
cfg.NetworkID = 133519467574833 // "yolov1"
|
||||
}
|
||||
cfg.Genesis = core.DefaultYoloV1GenesisBlock()
|
||||
case ctx.GlobalBool(DeveloperFlag.Name):
|
||||
|
@ -99,7 +99,7 @@ func TestRemoteMultiNotify(t *testing.T) {
|
||||
// Provide a results reader.
|
||||
// Otherwise the unread results will be logged asynchronously
|
||||
// and this can happen after the test is finished, causing a panic.
|
||||
results := make(chan *types.Block, cap(sink))
|
||||
results := make(chan consensus.ResultWithContext, cap(sink))
|
||||
|
||||
// Stream a lot of work task and ensure all the notifications bubble out.
|
||||
for i := 0; i < cap(sink); i++ {
|
||||
|
@ -28,7 +28,7 @@ import (
|
||||
"github.com/ledgerwatch/turbo-geth/accounts/scwallet"
|
||||
"github.com/ledgerwatch/turbo-geth/accounts/usbwallet"
|
||||
"github.com/ledgerwatch/turbo-geth/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/console/prompt"
|
||||
"github.com/ledgerwatch/turbo-geth/console/prompt"
|
||||
"github.com/ledgerwatch/turbo-geth/internal/jsre"
|
||||
"github.com/ledgerwatch/turbo-geth/rpc"
|
||||
)
|
||||
@ -469,7 +469,7 @@ func setError(resp *goja.Object, code int, msg string, data interface{}) {
|
||||
if data != nil {
|
||||
err["data"] = data
|
||||
}
|
||||
resp.Set("error", err)
|
||||
resp.Set("error", err) //nolint:errcheck
|
||||
}
|
||||
|
||||
// isNumber returns true if input value is a JS number.
|
||||
|
@ -14,13 +14,14 @@
|
||||
// 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/>.
|
||||
|
||||
//nolint:errcheck
|
||||
package console
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/dop251/goja"
|
||||
"github.com/ethereum/go-ethereum/internal/jsre"
|
||||
"github.com/ledgerwatch/turbo-geth/internal/jsre"
|
||||
)
|
||||
|
||||
// TestUndefinedAsParam ensures that personal functions can receive
|
||||
|
@ -29,8 +29,8 @@ import (
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
|
||||
"github.com/ledgerwatch/turbo-geth/common"
|
||||
"github.com/ledgerwatch/turbo-geth/console/prompt"
|
||||
"github.com/ledgerwatch/turbo-geth/consensus/ethash"
|
||||
"github.com/ledgerwatch/turbo-geth/console/prompt"
|
||||
"github.com/ledgerwatch/turbo-geth/core"
|
||||
"github.com/ledgerwatch/turbo-geth/eth"
|
||||
"github.com/ledgerwatch/turbo-geth/internal/jsre"
|
||||
|
@ -1497,7 +1497,7 @@ func (bc *BlockChain) insertChain(ctx context.Context, chain types.Blocks, verif
|
||||
"current", bc.CurrentBlock().Number().Uint64(), "currentHeader", bc.CurrentHeader().Number.Uint64())
|
||||
|
||||
// If the chain is terminating, don't even bother starting u
|
||||
if bc.getProcInterrupt() {
|
||||
if bc.insertStopped() {
|
||||
return 0, nil
|
||||
}
|
||||
// Start a parallel signature recovery (signer will fluke on fork transition, minimal perf loss)
|
||||
@ -2364,7 +2364,7 @@ type Pruner interface {
|
||||
func (bc *BlockChain) addJob() error {
|
||||
bc.quitMu.RLock()
|
||||
defer bc.quitMu.RUnlock()
|
||||
if bc.getProcInterrupt() {
|
||||
if bc.insertStopped() {
|
||||
return errors.New("blockchain is stopped")
|
||||
}
|
||||
bc.wg.Add(1)
|
||||
|
@ -27,7 +27,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/ledgerwatch/turbo-geth/common"
|
||||
"github.com/ledgerwatch/turbo-geth/core"
|
||||
"github.com/ledgerwatch/turbo-geth/core/types"
|
||||
"github.com/ledgerwatch/turbo-geth/log"
|
||||
"github.com/ledgerwatch/turbo-geth/params"
|
||||
)
|
||||
|
@ -1133,8 +1133,7 @@ func (pool *TxPool) runReorg(done chan struct{}, reset *txpoolResetRequest, dirt
|
||||
}
|
||||
}
|
||||
// Check for pending transactions for every account that sent new ones
|
||||
if pool.currentState != nil {
|
||||
promoted := pool.promoteExecutables(promoteAddrs)
|
||||
promoted := pool.promoteExecutables(promoteAddrs)
|
||||
|
||||
// If a new block appeared, validate the pool of pending transactions. This will
|
||||
// remove any transaction that has been included in the block or was invalidated
|
||||
@ -1147,11 +1146,9 @@ func (pool *TxPool) runReorg(done chan struct{}, reset *txpoolResetRequest, dirt
|
||||
pool.truncateQueue()
|
||||
|
||||
// Update all accounts to the latest known pending nonce
|
||||
if pool.currentState != nil {
|
||||
for addr, list := range pool.pending {
|
||||
txs := list.Flatten() // Heavy but will be cached and is needed by the miner anyway
|
||||
pool.pendingNonces.set(addr, txs[len(txs)-1].Nonce()+1)
|
||||
}
|
||||
for addr, list := range pool.pending {
|
||||
txs := list.Flatten() // Heavy but will be cached and is needed by the miner anyway
|
||||
pool.pendingNonces.set(addr, txs[len(txs)-1].Nonce()+1)
|
||||
}
|
||||
pool.mu.Unlock()
|
||||
|
||||
|
@ -110,12 +110,12 @@ func (c *Contract) isCode(udest uint64) bool {
|
||||
// Do we have a contract hash already?
|
||||
if c.CodeHash != (common.Hash{}) {
|
||||
// Does parent context have the analysis?
|
||||
analysis, exist := c.jumpdests[c.CodeHash]
|
||||
analysis, exist := c.dests.Get(c.CodeHash)
|
||||
if !exist {
|
||||
// Do the analysis and save in parent context
|
||||
// We do not need to store it in c.analysis
|
||||
analysis = codeBitmap(c.Code)
|
||||
c.jumpdests[c.CodeHash] = analysis
|
||||
c.dests.Set(c.CodeHash, analysis)
|
||||
}
|
||||
// Also stash it in current contract for faster access
|
||||
c.analysis = analysis
|
||||
|
@ -28,6 +28,7 @@ import (
|
||||
"github.com/ledgerwatch/turbo-geth/common/math"
|
||||
"github.com/ledgerwatch/turbo-geth/crypto"
|
||||
"github.com/ledgerwatch/turbo-geth/crypto/blake2b"
|
||||
"github.com/ledgerwatch/turbo-geth/crypto/bls12381"
|
||||
"github.com/ledgerwatch/turbo-geth/crypto/bn256"
|
||||
"github.com/ledgerwatch/turbo-geth/params"
|
||||
|
||||
@ -659,7 +660,9 @@ func (c *bls12381G1MultiExp) Run(input []byte) ([]byte, error) {
|
||||
|
||||
// Compute r = e_0 * p_0 + e_1 * p_1 + ... + e_(k-1) * p_(k-1)
|
||||
r := g.New()
|
||||
g.MultiExp(r, points, scalars)
|
||||
if _, err = g.MultiExp(r, points, scalars); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Encode the G1 point to 128 bytes
|
||||
return g.EncodePoint(r), nil
|
||||
@ -789,7 +792,9 @@ func (c *bls12381G2MultiExp) Run(input []byte) ([]byte, error) {
|
||||
|
||||
// Compute r = e_0 * p_0 + e_1 * p_1 + ... + e_(k-1) * p_(k-1)
|
||||
r := g.New()
|
||||
g.MultiExp(r, points, scalars)
|
||||
if _, err := g.MultiExp(r, points, scalars); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Encode the G2 point to 256 bytes.
|
||||
return g.EncodePoint(r), nil
|
||||
|
@ -74,7 +74,7 @@ func testPrecompiled(addr string, test precompiledTest, t *testing.T) {
|
||||
in := common.Hex2Bytes(test.Input)
|
||||
contract := NewContract(AccountRef(common.HexToAddress("1337")),
|
||||
nil, new(uint256.Int), p.RequiredGas(in), NewDestsCache(10))
|
||||
t.Run(fmt.Sprintf("%s-Gas=%d", test.name, contract.Gas), func(t *testing.T) {
|
||||
t.Run(fmt.Sprintf("%s-Gas=%d", test.Name, contract.Gas), func(t *testing.T) {
|
||||
if res, err := RunPrecompiledContract(p, in, contract); err != nil {
|
||||
t.Error(err)
|
||||
} else if common.Bytes2Hex(res) != test.Expected {
|
||||
@ -93,7 +93,7 @@ func testPrecompiledOOG(addr string, test precompiledTest, t *testing.T) {
|
||||
in := common.Hex2Bytes(test.Input)
|
||||
contract := NewContract(AccountRef(common.HexToAddress("1337")),
|
||||
nil, new(uint256.Int), p.RequiredGas(in)-1, NewDestsCache(10))
|
||||
t.Run(fmt.Sprintf("%s-Gas=%d", test.name, contract.Gas), func(t *testing.T) {
|
||||
t.Run(fmt.Sprintf("%s-Gas=%d", test.Name, contract.Gas), func(t *testing.T) {
|
||||
_, err := RunPrecompiledContract(p, in, contract)
|
||||
if err.Error() != "out of gas" {
|
||||
t.Errorf("Expected error [out of gas], got [%v]", err)
|
||||
|
@ -567,10 +567,10 @@ func opBeginSub(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) (
|
||||
}
|
||||
|
||||
func opJumpSub(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
if len(callContext.rstack.data) >= 1023 {
|
||||
if len(callContext.rstack.Data()) >= 1023 {
|
||||
return nil, ErrReturnStackExceeded
|
||||
}
|
||||
pos := callContext.stack.pop()
|
||||
pos := callContext.stack.Pop()
|
||||
if !pos.IsUint64() {
|
||||
return nil, ErrInvalidJump
|
||||
}
|
||||
@ -578,20 +578,19 @@ func opJumpSub(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([
|
||||
if !callContext.contract.validJumpSubdest(posU64) {
|
||||
return nil, ErrInvalidJump
|
||||
}
|
||||
callContext.rstack.push(*pc)
|
||||
callContext.rstack.Push(*pc)
|
||||
*pc = posU64 + 1
|
||||
interpreter.intPool.put(pos)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opReturnSub(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
if len(callContext.rstack.data) == 0 {
|
||||
if len(callContext.rstack.Data()) == 0 {
|
||||
return nil, ErrInvalidRetsub
|
||||
}
|
||||
// Other than the check that the return stack is not empty, there is no
|
||||
// need to validate the pc from 'returns', since we only ever push valid
|
||||
//values onto it via jumpsub.
|
||||
*pc = callContext.rstack.pop() + 1
|
||||
*pc = callContext.rstack.Pop() + 1
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
// 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/>.
|
||||
|
||||
//nolint:errcheck
|
||||
package vm
|
||||
|
||||
import (
|
||||
@ -96,8 +97,8 @@ func testTwoOperandOp(t *testing.T, tests []TwoOperandTestcase, opFn executionFu
|
||||
var (
|
||||
dests = NewDestsCache(100)
|
||||
env = NewEVM(Context{}, nil, params.TestChainConfig, Config{}, dests)
|
||||
rstack = stack.NewReturnStack()
|
||||
stack = stack.New()
|
||||
rstack = newReturnStack()
|
||||
pc = uint64(0)
|
||||
evmInterpreter = env.interpreter.(*EVMInterpreter)
|
||||
)
|
||||
@ -195,8 +196,8 @@ func getResult(args []*twoOperandParams, opFn executionFunc) []TwoOperandTestcas
|
||||
var (
|
||||
dests = NewDestsCache(100)
|
||||
env = NewEVM(Context{}, nil, params.TestChainConfig, Config{}, dests)
|
||||
rstack = stack.NewReturnStack()
|
||||
stack = stack.New()
|
||||
rstack = newReturnStack()
|
||||
pc = uint64(0)
|
||||
interpreter = env.interpreter.(*EVMInterpreter)
|
||||
)
|
||||
@ -247,8 +248,8 @@ func opBenchmark(bench *testing.B, op executionFunc, args ...string) {
|
||||
var (
|
||||
dests = NewDestsCache(100)
|
||||
env = NewEVM(Context{}, nil, params.TestChainConfig, Config{}, dests)
|
||||
rstack = stack.NewReturnStack()
|
||||
stack = stack.New()
|
||||
rstack = newReturnStack()
|
||||
evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
|
||||
)
|
||||
|
||||
@ -482,8 +483,8 @@ func TestOpMstore(t *testing.T) {
|
||||
var (
|
||||
dests = NewDestsCache(100)
|
||||
env = NewEVM(Context{}, nil, params.TestChainConfig, Config{}, dests)
|
||||
rstack = stack.NewReturnStack()
|
||||
stack = stack.New()
|
||||
rstack = newReturnStack()
|
||||
mem = NewMemory()
|
||||
evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
|
||||
)
|
||||
@ -510,8 +511,8 @@ func BenchmarkOpMstore(bench *testing.B) {
|
||||
var (
|
||||
dests = NewDestsCache(100)
|
||||
env = NewEVM(Context{}, nil, params.TestChainConfig, Config{}, dests)
|
||||
rstack = stack.NewReturnStack()
|
||||
stack = stack.New()
|
||||
rstack = newReturnStack()
|
||||
mem = NewMemory()
|
||||
evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
|
||||
)
|
||||
@ -534,8 +535,8 @@ func BenchmarkOpSHA3(bench *testing.B) {
|
||||
var (
|
||||
dests = NewDestsCache(100)
|
||||
env = NewEVM(Context{}, nil, params.TestChainConfig, Config{}, dests)
|
||||
rstack = stack.NewReturnStack()
|
||||
stack = stack.New()
|
||||
rstack = newReturnStack()
|
||||
mem = NewMemory()
|
||||
evmInterpreter = NewEVMInterpreter(env, env.vmConfig)
|
||||
)
|
||||
|
@ -67,7 +67,7 @@ type Interpreter interface {
|
||||
type callCtx struct {
|
||||
memory *Memory
|
||||
stack *stack.Stack
|
||||
rstack *ReturnStack
|
||||
rstack *stack.ReturnStack
|
||||
contract *Contract
|
||||
}
|
||||
|
||||
@ -97,8 +97,8 @@ type EVMInterpreter struct {
|
||||
func NewEVMInterpreter(evm *EVM, cfg Config) *EVMInterpreter {
|
||||
var jt *JumpTable
|
||||
switch {
|
||||
case evm.chainRules.IsYoloV1:
|
||||
jt = yoloV1InstructionSet
|
||||
case evm.chainRules.IsYoloV1:
|
||||
jt = &yoloV1InstructionSet
|
||||
case evm.chainRules.IsIstanbul:
|
||||
jt = &istanbulInstructionSet
|
||||
case evm.chainRules.IsConstantinople:
|
||||
@ -161,10 +161,10 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
|
||||
}
|
||||
|
||||
var (
|
||||
op OpCode // current opcode
|
||||
mem = NewMemory() // bound memory
|
||||
op OpCode // current opcode
|
||||
mem = NewMemory() // bound memory
|
||||
locStack = pool.StackPool.Get()
|
||||
returns = newReturnStack() // local returns stack
|
||||
returns = stack.NewReturnStack() // local returns stack
|
||||
callContext = &callCtx{
|
||||
memory: mem,
|
||||
stack: locStack,
|
||||
|
@ -106,8 +106,8 @@ func (s *StructLog) ErrorString() string {
|
||||
// if you need to retain them beyond the current call.
|
||||
type Tracer interface {
|
||||
CaptureStart(depth int, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) error
|
||||
CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *stack.Stack, rStack *ReturnStack, contract *Contract, depth int, err error) error
|
||||
CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *stack.Stack, rStack *ReturnStack, contract *Contract, depth int, err error) error
|
||||
CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *stack.Stack, rStack *stack.ReturnStack, contract *Contract, depth int, err error) error
|
||||
CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *stack.Stack, rStack *stack.ReturnStack, contract *Contract, depth int, err error) error
|
||||
CaptureEnd(depth int, output []byte, gasUsed uint64, t time.Duration, err error) error
|
||||
CaptureCreate(creator common.Address, creation common.Address) error
|
||||
CaptureAccountRead(account common.Address) error
|
||||
@ -147,7 +147,7 @@ func (l *StructLogger) CaptureStart(depth int, from common.Address, to common.Ad
|
||||
// CaptureState logs a new structured log message and pushes it out to the environment
|
||||
//
|
||||
// CaptureState also tracks SSTORE ops to track dirty values.
|
||||
func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *stack.Stack, rStack *ReturnStack, contract *Contract, depth int, err error) error {
|
||||
func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *stack.Stack, rStack *stack.ReturnStack, contract *Contract, depth int, err error) error {
|
||||
// check if already accumulated the specified number of logs
|
||||
if l.cfg.Limit != 0 && l.cfg.Limit <= len(l.logs) {
|
||||
return errTraceLimitReached
|
||||
@ -189,8 +189,8 @@ func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost ui
|
||||
}
|
||||
var rstack []uint64
|
||||
if !l.cfg.DisableStack && rStack != nil {
|
||||
rstck := make([]uint64, len(rStack.data))
|
||||
copy(rstck, rStack.data)
|
||||
rstck := make([]uint64, len(rStack.Data()))
|
||||
copy(rstck, rStack.Data())
|
||||
}
|
||||
// create a new snapshot of the EVM.
|
||||
log := StructLog{pc, op, gas, cost, mem, memory.Len(), stck, rstack, storage, depth, env.IntraBlockState.GetRefund(), err}
|
||||
@ -201,7 +201,7 @@ func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost ui
|
||||
|
||||
// CaptureFault implements the Tracer interface to trace an execution fault
|
||||
// while running an opcode.
|
||||
func (l *StructLogger) CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *stack.Stack, rStack *ReturnStack, contract *Contract, depth int, err error) error {
|
||||
func (l *StructLogger) CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *stack.Stack, rStack *stack.ReturnStack, contract *Contract, depth int, err error) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -306,7 +306,7 @@ func NewMarkdownLogger(cfg *LogConfig, writer io.Writer) *mdLogger {
|
||||
return l
|
||||
}
|
||||
|
||||
func (t *mdLogger) CaptureStart(from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) error {
|
||||
func (t *mdLogger) CaptureStart(from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) error { //nolint:interfacer
|
||||
if !create {
|
||||
fmt.Fprintf(t.out, "From: `%v`\nTo: `%v`\nData: `0x%x`\nGas: `%d`\nValue `%v` wei\n",
|
||||
from.String(), to.String(),
|
||||
@ -324,12 +324,12 @@ func (t *mdLogger) CaptureStart(from common.Address, to common.Address, create b
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *mdLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, rStack *ReturnStack, contract *Contract, depth int, err error) error {
|
||||
func (t *mdLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *stack.Stack, rStack *stack.ReturnStack, contract *Contract, depth int, err error) error {
|
||||
fmt.Fprintf(t.out, "| %4d | %10v | %3d |", pc, op, cost)
|
||||
|
||||
if !t.cfg.DisableStack { // format stack
|
||||
var a []string
|
||||
for _, elem := range stack.data {
|
||||
for _, elem := range stack.GetData() {
|
||||
a = append(a, fmt.Sprintf("%d", elem))
|
||||
}
|
||||
b := fmt.Sprintf("[%v]", strings.Join(a, ","))
|
||||
@ -337,7 +337,7 @@ func (t *mdLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64
|
||||
}
|
||||
if !t.cfg.DisableStack { // format return stack
|
||||
var a []string
|
||||
for _, elem := range rStack.data {
|
||||
for _, elem := range rStack.Data() {
|
||||
a = append(a, fmt.Sprintf("%2d", elem))
|
||||
}
|
||||
b := fmt.Sprintf("[%v]", strings.Join(a, ","))
|
||||
@ -350,7 +350,7 @@ func (t *mdLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *mdLogger) CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, rStack *ReturnStack, contract *Contract, depth int, err error) error {
|
||||
func (t *mdLogger) CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *stack.Stack, rStack *stack.ReturnStack, contract *Contract, depth int, err error) error {
|
||||
|
||||
fmt.Fprintf(t.out, "\nError: at pc=%d, op=%v: %v\n", pc, op, err)
|
||||
|
||||
|
@ -47,7 +47,7 @@ func (l *JSONLogger) CaptureStart(depth int, from common.Address, to common.Addr
|
||||
}
|
||||
|
||||
// CaptureState outputs state information on the logger.
|
||||
func (l *JSONLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *stack.Stack, rStack *ReturnStack, contract *Contract, depth int, err error) error {
|
||||
func (l *JSONLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *stack.Stack, rStack *stack.ReturnStack, contract *Contract, depth int, err error) error {
|
||||
log := StructLog{
|
||||
Pc: pc,
|
||||
Op: op,
|
||||
@ -64,7 +64,7 @@ func (l *JSONLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint
|
||||
}
|
||||
if !l.cfg.DisableStack {
|
||||
log.Stack = make([]*big.Int, len(stack.GetData()))
|
||||
log.ReturnStack = rStack.data
|
||||
log.ReturnStack = rStack.Data()
|
||||
for i, item := range stack.GetData() {
|
||||
log.Stack[i] = item.ToBig()
|
||||
}
|
||||
@ -73,7 +73,7 @@ func (l *JSONLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint
|
||||
}
|
||||
|
||||
// CaptureFault outputs state information on the logger.
|
||||
func (l *JSONLogger) CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *stack.Stack, rStack *ReturnStack, contract *Contract, depth int, err error) error {
|
||||
func (l *JSONLogger) CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *stack.Stack, rStack *stack.ReturnStack, contract *Contract, depth int, err error) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -57,14 +57,16 @@ func TestStoreCapture(t *testing.T) {
|
||||
env = NewEVM(Context{}, &dummyStatedb{}, params.TestChainConfig, Config{}, dests)
|
||||
logger = NewStructLogger(nil)
|
||||
mem = NewMemory()
|
||||
rstack = stack.NewReturnStack()
|
||||
stack = stack.New()
|
||||
rstack = newReturnStack()
|
||||
contract = NewContract(&dummyContractRef{}, &dummyContractRef{}, new(uint256.Int), 0, NewDestsCache(10))
|
||||
)
|
||||
stack.Push(uint256.NewInt().SetOne())
|
||||
stack.Push(uint256.NewInt())
|
||||
var index common.Hash
|
||||
logger.CaptureState(env, 0, SSTORE, 0, 0, mem, stack, rstack, contract, 0, nil)
|
||||
if err := logger.CaptureState(env, 0, SSTORE, 0, 0, mem, stack, rstack, contract, 0, nil); err != nil {
|
||||
t.Fatalf("error while caturing state %v", err)
|
||||
}
|
||||
if len(logger.changedValues[contract.Address()]) == 0 {
|
||||
t.Fatalf("expected exactly 1 changed value on address %x, got %d", contract.Address(), len(logger.changedValues[contract.Address()]))
|
||||
}
|
||||
|
@ -28,9 +28,11 @@ import (
|
||||
"github.com/ledgerwatch/turbo-geth/common"
|
||||
"github.com/ledgerwatch/turbo-geth/consensus"
|
||||
"github.com/ledgerwatch/turbo-geth/core"
|
||||
"github.com/ledgerwatch/turbo-geth/core/asm"
|
||||
"github.com/ledgerwatch/turbo-geth/core/state"
|
||||
"github.com/ledgerwatch/turbo-geth/core/types"
|
||||
"github.com/ledgerwatch/turbo-geth/core/vm"
|
||||
"github.com/ledgerwatch/turbo-geth/core/vm/stack"
|
||||
"github.com/ledgerwatch/turbo-geth/ethdb"
|
||||
"github.com/ledgerwatch/turbo-geth/params"
|
||||
)
|
||||
@ -347,7 +349,7 @@ func BenchmarkSimpleLoop(b *testing.B) {
|
||||
// }})
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
Execute(code, nil, nil)
|
||||
_, _, _ = Execute(code, nil, nil, 0)
|
||||
}
|
||||
}
|
||||
|
||||
@ -356,28 +358,41 @@ type stepCounter struct {
|
||||
steps int
|
||||
}
|
||||
|
||||
func (s *stepCounter) CaptureStart(from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) error {
|
||||
func (s *stepCounter) CaptureStart(_ int, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *stepCounter) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *vm.Stack, rStack *vm.ReturnStack, contract *vm.Contract, depth int, err error) error {
|
||||
func (s *stepCounter) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, rStack *stack.ReturnStack, contract *vm.Contract, depth int, err error) error {
|
||||
s.steps++
|
||||
// Enable this for more output
|
||||
//s.inner.CaptureState(env, pc, op, gas, cost, memory, stack, rStack, contract, depth, err)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *stepCounter) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *vm.Stack, rStack *vm.ReturnStack, contract *vm.Contract, depth int, err error) error {
|
||||
func (s *stepCounter) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, rStack *stack.ReturnStack, contract *vm.Contract, depth int, err error) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *stepCounter) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) error {
|
||||
func (s *stepCounter) CaptureEnd(_ int, output []byte, gasUsed uint64, t time.Duration, err error) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *stepCounter) CaptureCreate(creator common.Address, creation common.Address) error {
|
||||
return nil
|
||||
}
|
||||
func (s *stepCounter) CaptureAccountRead(account common.Address) error {
|
||||
return nil
|
||||
}
|
||||
func (s *stepCounter) CaptureAccountWrite(account common.Address) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestJumpSub1024Limit(t *testing.T) {
|
||||
state, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
|
||||
address := common.HexToAddress("0x0a")
|
||||
var (
|
||||
tds = state.NewTrieDbState(common.Hash{}, ethdb.NewMemDatabase(), 0)
|
||||
state = state.New(tds)
|
||||
address = common.HexToAddress("0x0a")
|
||||
)
|
||||
// Code is
|
||||
// 0 beginsub
|
||||
// 1 push 0
|
||||
@ -413,8 +428,11 @@ func TestJumpSub1024Limit(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestReturnSubShallow(t *testing.T) {
|
||||
state, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
|
||||
address := common.HexToAddress("0x0a")
|
||||
var (
|
||||
tds = state.NewTrieDbState(common.Hash{}, ethdb.NewMemDatabase(), 0)
|
||||
state = state.New(tds)
|
||||
address = common.HexToAddress("0x0a")
|
||||
)
|
||||
// The code does returnsub without having anything on the returnstack.
|
||||
// It should not panic, but just fail after one step
|
||||
state.SetCode(address, []byte{
|
||||
@ -449,21 +467,24 @@ func TestReturnSubShallow(t *testing.T) {
|
||||
|
||||
// disabled -- only used for generating markdown
|
||||
func DisabledTestReturnCases(t *testing.T) {
|
||||
tracer := stepCounter{inner: vm.NewJSONLogger(nil, os.Stdout)}
|
||||
cfg := &Config{
|
||||
EVMConfig: vm.Config{
|
||||
Debug: true,
|
||||
Tracer: vm.NewMarkdownLogger(nil, os.Stdout),
|
||||
Tracer: &tracer,
|
||||
ExtraEips: []int{2315},
|
||||
},
|
||||
}
|
||||
// This should fail at first opcode
|
||||
//nolint:errcheck
|
||||
Execute([]byte{
|
||||
byte(vm.RETURNSUB),
|
||||
byte(vm.PC),
|
||||
byte(vm.PC),
|
||||
}, nil, cfg)
|
||||
}, nil, cfg, 0)
|
||||
|
||||
// Should also fail
|
||||
//nolint:errcheck
|
||||
Execute([]byte{
|
||||
byte(vm.PUSH1), 5,
|
||||
byte(vm.JUMPSUB),
|
||||
@ -472,9 +493,10 @@ func DisabledTestReturnCases(t *testing.T) {
|
||||
byte(vm.BEGINSUB),
|
||||
byte(vm.RETURNSUB),
|
||||
byte(vm.PC),
|
||||
}, nil, cfg)
|
||||
}, nil, cfg, 0)
|
||||
|
||||
// This should complete
|
||||
//nolint:errcheck
|
||||
Execute([]byte{
|
||||
byte(vm.PUSH1), 0x4,
|
||||
byte(vm.JUMPSUB),
|
||||
@ -485,17 +507,18 @@ func DisabledTestReturnCases(t *testing.T) {
|
||||
byte(vm.RETURNSUB),
|
||||
byte(vm.BEGINSUB),
|
||||
byte(vm.RETURNSUB),
|
||||
}, nil, cfg)
|
||||
}, nil, cfg, 0)
|
||||
}
|
||||
|
||||
// DisabledTestEipExampleCases contains various testcases that are used for the
|
||||
// EIP examples
|
||||
// This test is disabled, as it's only used for generating markdown
|
||||
func DisabledTestEipExampleCases(t *testing.T) {
|
||||
tracer := stepCounter{inner: vm.NewJSONLogger(nil, os.Stdout)}
|
||||
cfg := &Config{
|
||||
EVMConfig: vm.Config{
|
||||
Debug: true,
|
||||
Tracer: vm.NewMarkdownLogger(nil, os.Stdout),
|
||||
Tracer: &tracer,
|
||||
ExtraEips: []int{2315},
|
||||
},
|
||||
}
|
||||
@ -514,7 +537,7 @@ func DisabledTestEipExampleCases(t *testing.T) {
|
||||
fmt.Printf("%v\nBytecode: `0x%x` (`%v`)\n",
|
||||
comment,
|
||||
code, ops)
|
||||
Execute(code, nil, cfg)
|
||||
Execute(code, nil, cfg, 0) //nolint:errcheck
|
||||
}
|
||||
|
||||
{ // First eip testcase
|
||||
|
@ -99,16 +99,20 @@ type ReturnStack struct {
|
||||
data []uint64
|
||||
}
|
||||
|
||||
func newReturnStack() *ReturnStack {
|
||||
func NewReturnStack() *ReturnStack {
|
||||
return &ReturnStack{data: make([]uint64, 0, 1024)}
|
||||
}
|
||||
|
||||
func (st *ReturnStack) push(d uint64) {
|
||||
func (st *ReturnStack) Push(d uint64) {
|
||||
st.data = append(st.data, d)
|
||||
}
|
||||
|
||||
func (st *ReturnStack) pop() (ret uint64) {
|
||||
func (st *ReturnStack) Pop() (ret uint64) {
|
||||
ret = st.data[len(st.data)-1]
|
||||
st.data = st.data[:len(st.data)-1]
|
||||
return
|
||||
}
|
||||
|
||||
func (st *ReturnStack) Data() []uint64 {
|
||||
return st.data
|
||||
}
|
||||
|
@ -14,6 +14,7 @@
|
||||
// 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/>.
|
||||
|
||||
//nolint:gofmt
|
||||
package bls12381
|
||||
|
||||
/*
|
||||
|
@ -14,6 +14,7 @@
|
||||
// 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/>.
|
||||
|
||||
//nolint:stylecheck
|
||||
package bls12381
|
||||
|
||||
import (
|
||||
@ -176,6 +177,7 @@ func (e *fe) sign() bool {
|
||||
return r[0]&1 == 0
|
||||
}
|
||||
|
||||
//nolint:unparam
|
||||
func (fe *fe) div2(e uint64) {
|
||||
fe[0] = fe[0]>>1 | fe[1]<<63
|
||||
fe[1] = fe[1]>>1 | fe[2]<<63
|
||||
|
@ -127,7 +127,7 @@ func inverse(inv, e *fe) {
|
||||
laddAssign(s, r)
|
||||
z += r.mul2()
|
||||
}
|
||||
k += 1
|
||||
k++
|
||||
}
|
||||
|
||||
if !found {
|
||||
|
@ -462,7 +462,7 @@ func TestFpNonResidue(t *testing.T) {
|
||||
t.Fatal("element is quadratic non residue, 2", i)
|
||||
}
|
||||
} else {
|
||||
i -= 1
|
||||
i--
|
||||
}
|
||||
}
|
||||
|
||||
@ -846,7 +846,7 @@ func TestFp2NonResidue(t *testing.T) {
|
||||
t.Fatal("element is quadratic non residue, 2", i)
|
||||
}
|
||||
} else {
|
||||
i -= 1
|
||||
i--
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1393,6 +1393,7 @@ func BenchmarkMultiplication(t *testing.B) {
|
||||
}
|
||||
}
|
||||
|
||||
//nolint:unparam
|
||||
func padBytes(in []byte, size int) []byte {
|
||||
out := make([]byte, size)
|
||||
if len(in) > size {
|
||||
|
@ -14,6 +14,7 @@
|
||||
// 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/>.
|
||||
|
||||
//nolint:golint
|
||||
package bls12381
|
||||
|
||||
import (
|
||||
|
@ -6,7 +6,7 @@ import (
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ledgerwatch/turbo-geth/common"
|
||||
)
|
||||
|
||||
func (g *G1) one() *PointG1 {
|
||||
|
@ -14,6 +14,7 @@
|
||||
// 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/>.
|
||||
|
||||
//noling:golint
|
||||
package bls12381
|
||||
|
||||
import (
|
||||
@ -287,7 +288,7 @@ func (g *G2) Add(r, p1, p2 *PointG2) *PointG2 {
|
||||
if t[1].equal(t[3]) {
|
||||
if t[0].equal(t[2]) {
|
||||
return g.Double(r, p1)
|
||||
} else {
|
||||
} else { //nolint:golint
|
||||
return r.Zero()
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import (
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ledgerwatch/turbo-geth/common"
|
||||
)
|
||||
|
||||
func (g *G2) one() *PointG2 {
|
||||
|
@ -14,6 +14,7 @@
|
||||
// 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/>.
|
||||
|
||||
//nolint:stylecheck
|
||||
package bls12381
|
||||
|
||||
import (
|
||||
|
@ -14,6 +14,7 @@
|
||||
// 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/>.
|
||||
|
||||
//nolint:gofmt
|
||||
package bls12381
|
||||
|
||||
// isogenyMapG1 applies 11-isogeny map for BLS12-381 G1 defined at draft-irtf-cfrg-hash-to-curve-06.
|
||||
|
@ -194,14 +194,14 @@ func (e *Engine) millerLoop(f *fe12) {
|
||||
if i != 62 {
|
||||
fp12.square(f, f)
|
||||
}
|
||||
for i := 0; i <= len(pairs)-1; i++ {
|
||||
for i := 0; i <= len(pairs)-1; i++ { //nolint:govet
|
||||
fp2.mulByFq(t[0], &ellCoeffs[i][j][2], &pairs[i].g1[1])
|
||||
fp2.mulByFq(t[1], &ellCoeffs[i][j][1], &pairs[i].g1[0])
|
||||
fp12.mulBy014Assign(f, &ellCoeffs[i][j][0], t[1], t[0])
|
||||
}
|
||||
if x.Bit(i) != 0 {
|
||||
j++
|
||||
for i := 0; i <= len(pairs)-1; i++ {
|
||||
for i := 0; i <= len(pairs)-1; i++ { //nolint:govet
|
||||
fp2.mulByFq(t[0], &ellCoeffs[i][j][2], &pairs[i].g1[1])
|
||||
fp2.mulByFq(t[1], &ellCoeffs[i][j][1], &pairs[i].g1[0])
|
||||
fp12.mulBy014Assign(f, &ellCoeffs[i][j][0], t[1], t[0])
|
||||
|
@ -4,7 +4,7 @@ import (
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ledgerwatch/turbo-geth/common"
|
||||
)
|
||||
|
||||
func TestPairingExpected(t *testing.T) {
|
||||
|
@ -20,7 +20,7 @@ import (
|
||||
"errors"
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ledgerwatch/turbo-geth/common"
|
||||
)
|
||||
|
||||
func bigFromHex(hex string) *big.Int {
|
||||
|
@ -250,7 +250,7 @@ func (dl *downloadTester) InsertHeaderChain(headers []*types.Header, checkFreq i
|
||||
|
||||
// Do a quick check, as the blockchain.InsertHeaderChain doesn't insert anything in case of errors
|
||||
if _, ok := dl.ownHeaders[headers[0].ParentHash]; !ok {
|
||||
return 0, errors.New("InsertHeaderChain: unknown parent at first position")
|
||||
return 0, errors.New("error in InsertHeaderChain: unknown parent at first position")
|
||||
}
|
||||
var hashes []common.Hash
|
||||
for i := 1; i < len(headers); i++ {
|
||||
@ -269,7 +269,7 @@ func (dl *downloadTester) InsertHeaderChain(headers []*types.Header, checkFreq i
|
||||
}
|
||||
if _, ok := dl.ownHeaders[header.ParentHash]; !ok {
|
||||
// This _should_ be impossible, due to precheck and induction
|
||||
return i, fmt.Errorf("InsertHeaderChain: unknown parent at position %d", i)
|
||||
return i, fmt.Errorf("error in InsertHeaderChain: unknown parent at position %d", i)
|
||||
}
|
||||
dl.ownHashes = append(dl.ownHashes, hash)
|
||||
dl.ownHeaders[hash] = header
|
||||
@ -297,7 +297,7 @@ func (dl *downloadTester) InsertChain(_ context.Context, blocks types.Blocks) (i
|
||||
|
||||
for i, block := range blocks {
|
||||
if _, ok := dl.ownBlocks[block.ParentHash()]; !ok {
|
||||
return i, fmt.Errorf("InsertChain: unknown parent at position %d / %d", i, len(blocks))
|
||||
return i, fmt.Errorf("error in InsertChain: unknown parent at position %d / %d", i, len(blocks))
|
||||
}
|
||||
if _, ok := dl.ownHeaders[block.Hash()]; !ok {
|
||||
dl.ownHashes = append(dl.ownHashes, block.Hash())
|
||||
@ -325,7 +325,7 @@ func (dl *downloadTester) InsertReceiptChain(blocks types.Blocks, receipts []typ
|
||||
}
|
||||
if _, ok := dl.ancientBlocks[blocks[i].ParentHash()]; !ok {
|
||||
if _, ok := dl.ownBlocks[blocks[i].ParentHash()]; !ok {
|
||||
return i, errors.New("InsertReceiptChain: unknown parent")
|
||||
return i, errors.New("error in InsertReceiptChain: unknown parent")
|
||||
}
|
||||
}
|
||||
if blocks[i].NumberU64() <= ancientLimit {
|
||||
|
@ -549,7 +549,7 @@ func (jst *Tracer) CaptureStart(depth int, from common.Address, to common.Addres
|
||||
}
|
||||
|
||||
// CaptureState implements the Tracer interface to trace a single step of VM execution.
|
||||
func (jst *Tracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, rStack *vm.ReturnStack, contract *vm.Contract, depth int, err error) error {
|
||||
func (jst *Tracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, rStack *stack.ReturnStack, contract *vm.Contract, depth int, err error) error {
|
||||
if jst.err == nil {
|
||||
// Initialize the context if it wasn't done yet
|
||||
if !jst.inited {
|
||||
@ -588,7 +588,7 @@ func (jst *Tracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost
|
||||
|
||||
// CaptureFault implements the Tracer interface to trace an execution fault
|
||||
// while running an opcode.
|
||||
func (jst *Tracer) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, rStack *vm.ReturnStack, contract *vm.Contract, depth int, err error) error {
|
||||
func (jst *Tracer) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, rStack *stack.ReturnStack, contract *vm.Contract, depth int, err error) error {
|
||||
if jst.err == nil {
|
||||
// Apart from the error, everything matches the previous invocation
|
||||
jst.errorValue = new(string)
|
||||
|
@ -171,10 +171,10 @@ func TestHaltBetweenSteps(t *testing.T) {
|
||||
env := vm.NewEVM(vm.Context{BlockNumber: big.NewInt(1)}, &dummyStatedb{}, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer}, nil)
|
||||
contract := vm.NewContract(&account{}, &account{}, uint256.NewInt(), 0, vm.NewDestsCache(50000))
|
||||
|
||||
tracer.CaptureState(env, 0, 0, 0, 0, nil, nil, nil, contract, 0, nil)
|
||||
tracer.CaptureState(env, 0, 0, 0, 0, nil, nil, nil, contract, 0, nil) //nolint:errcheck
|
||||
timeout := errors.New("stahp")
|
||||
tracer.Stop(timeout)
|
||||
tracer.CaptureState(env, 0, 0, 0, 0, nil, nil, nil, contract, 0, nil)
|
||||
tracer.CaptureState(env, 0, 0, 0, 0, nil, nil, nil, contract, 0, nil) //nolint:errcheck
|
||||
|
||||
if _, err := tracer.GetResult(); err.Error() != timeout.Error() {
|
||||
t.Errorf("Expected timeout error, got %v", err)
|
||||
|
10
go.mod
10
go.mod
@ -4,6 +4,7 @@ go 1.13
|
||||
|
||||
require (
|
||||
github.com/AskAlexSharov/lmdb-go v1.9.0
|
||||
github.com/Azure/azure-pipeline-go v0.2.2 // indirect
|
||||
github.com/Azure/azure-storage-blob-go v0.8.0
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.3 // indirect
|
||||
github.com/JekaMas/notify v0.9.4
|
||||
@ -18,12 +19,12 @@ require (
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea
|
||||
github.com/dgraph-io/badger/v2 v2.0.3
|
||||
github.com/dlclark/regexp2 v1.2.0 // indirect
|
||||
github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf
|
||||
github.com/dop251/goja v0.0.0-20200219165308-d1232e640a87
|
||||
github.com/dustin/go-humanize v1.0.0
|
||||
github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c
|
||||
github.com/ethereum/evmc/v7 v7.3.0
|
||||
github.com/ethereum/go-ethereum v1.9.15
|
||||
github.com/fatih/color v1.7.0
|
||||
github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc
|
||||
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff
|
||||
@ -33,6 +34,7 @@ require (
|
||||
github.com/go-stack/stack v1.8.0
|
||||
github.com/golang/protobuf v1.3.3
|
||||
github.com/golang/snappy v0.0.1
|
||||
github.com/google/go-cmp v0.3.1 // indirect
|
||||
github.com/gorilla/websocket v1.4.1
|
||||
github.com/graph-gophers/graphql-go v0.0.0-20191115155744-f33e81362277
|
||||
github.com/hashicorp/golang-lru v0.5.4
|
||||
@ -42,10 +44,12 @@ require (
|
||||
github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458
|
||||
github.com/julienschmidt/httprouter v1.2.0
|
||||
github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356
|
||||
github.com/kylelemons/godebug v1.1.0 // indirect
|
||||
github.com/ledgerwatch/bolt v1.4.6-0.20200605053542-69293d8f1d33
|
||||
github.com/llgcode/draw2d v0.0.0-20180825133448-f52c8a71aff0
|
||||
github.com/mattn/go-colorable v0.1.2
|
||||
github.com/mattn/go-isatty v0.0.12
|
||||
github.com/naoina/go-stringutil v0.1.0 // indirect
|
||||
github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416
|
||||
github.com/olekukonko/tablewriter v0.0.2-0.20190409134802-7e037d187b0c
|
||||
github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222
|
||||
@ -59,6 +63,7 @@ require (
|
||||
github.com/spf13/cobra v1.0.0
|
||||
github.com/status-im/keycard-go v0.0.0-20190424133014-d95853db0f48
|
||||
github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570
|
||||
github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3 // indirect
|
||||
github.com/stretchr/testify v1.5.1
|
||||
github.com/tyler-smith/go-bip39 v1.0.2
|
||||
github.com/ugorji/go/codec v1.1.7
|
||||
@ -74,5 +79,6 @@ require (
|
||||
golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15
|
||||
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce
|
||||
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200603215123-a4a8cb9d2cbc
|
||||
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200603215123-a4a8cb9d2cbc
|
||||
gotest.tools v2.2.0+incompatible // indirect
|
||||
)
|
||||
|
14
go.sum
14
go.sum
@ -3,6 +3,8 @@ github.com/AskAlexSharov/lmdb-go v1.9.0 h1:lXbgv+ERzRsLOiZi53tu2MOLuOZy6vSLFL8ql
|
||||
github.com/AskAlexSharov/lmdb-go v1.9.0/go.mod h1:k7Jo/kN60Hq1MTBwsVSp2JllEs5Tyhd4MZ7tY9smjeA=
|
||||
github.com/Azure/azure-pipeline-go v0.2.1 h1:OLBdZJ3yvOn2MezlWvbrBMTEUQC72zAftRZOMdj5HYo=
|
||||
github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4=
|
||||
github.com/Azure/azure-pipeline-go v0.2.2 h1:6oiIS9yaG6XCCzhgAgKFfIWyo4LLCiDhZot6ltoThhY=
|
||||
github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc=
|
||||
github.com/Azure/azure-storage-blob-go v0.8.0 h1:53qhf0Oxa0nOjgbDeeYPUeyiNmafAFEY95rZLK0Tj6o=
|
||||
github.com/Azure/azure-storage-blob-go v0.8.0/go.mod h1:lPI3aLPpuLTeUwh1sViKXFxwl2B6teiRqI0deQUvsw0=
|
||||
github.com/Azure/go-autorest/autorest v0.9.0 h1:MRvx8gncNaXJqOoLmhNjUAKh33JJF8LyxPhomEtOsjs=
|
||||
@ -92,8 +94,6 @@ github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c h1:JHHhtb9XWJrGNMcrVP6vyzO4dusgi/HnceHTgxSejUM=
|
||||
github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||
github.com/elastic/gosigar v0.8.1-0.20180330100440-37f05ff46ffa h1:XKAhUk/dtp+CV0VO6mhG2V7jA9vbcGcnYF/Ay9NjZrY=
|
||||
github.com/elastic/gosigar v0.8.1-0.20180330100440-37f05ff46ffa/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs=
|
||||
github.com/ethereum/evmc/v7 v7.3.0 h1:4CsjJ+vSRrkzxOHeG1lFRGk4sG4/PgzXnWuRNgLGMJ0=
|
||||
github.com/ethereum/evmc/v7 v7.3.0/go.mod h1:q2Q0rCSUlIkngd+mZwfCzEUbvB0IIopH1+7hcs9QuDg=
|
||||
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
|
||||
@ -147,6 +147,8 @@ github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
|
||||
@ -206,6 +208,8 @@ github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx
|
||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149 h1:HfxbT6/JcvIljmERptWhwa8XzP7H3T+Z2N26gTsaDaA=
|
||||
github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
|
||||
github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d h1:oNAwILwmgWKFpuU+dXvI6dl9jG2mAWAZLX3r9s0PPiw=
|
||||
github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
@ -267,6 +271,8 @@ github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNue
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/shirou/gopsutil v2.20.5-0.20200531151128-663af789c085+incompatible h1:+gAR1bMhuoQnZMTWFIvp7ukynULPsteLzG+siZKLtD8=
|
||||
github.com/shirou/gopsutil v2.20.5-0.20200531151128-663af789c085+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
@ -385,8 +391,8 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogR
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU=
|
||||
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c=
|
||||
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200316214253-d7b0ff38cac9 h1:ITeyKbRetrVzqR3U1eY+ywgp7IBspGd1U/bkwd1gWu4=
|
||||
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200316214253-d7b0ff38cac9/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
|
||||
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200603215123-a4a8cb9d2cbc h1:17cdygvFw3DEyNMh81Bk687W74d5pcC5qEKQICv9N6g=
|
||||
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200603215123-a4a8cb9d2cbc/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
@ -19,7 +19,7 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ledgerwatch/turbo-geth/log"
|
||||
"github.com/shirou/gopsutil/cpu"
|
||||
)
|
||||
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/metrics"
|
||||
"github.com/ledgerwatch/turbo-geth/metrics"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
|
@ -24,6 +24,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/ledgerwatch/turbo-geth/crypto"
|
||||
"github.com/ledgerwatch/turbo-geth/p2p/discover/v4wire"
|
||||
"github.com/ledgerwatch/turbo-geth/p2p/enode"
|
||||
"github.com/ledgerwatch/turbo-geth/p2p/enr"
|
||||
)
|
||||
|
@ -31,8 +31,8 @@ import (
|
||||
|
||||
"github.com/ledgerwatch/turbo-geth/crypto"
|
||||
"github.com/ledgerwatch/turbo-geth/log"
|
||||
"github.com/ledgerwatch/turbo-geth/p2p/discover/v4wire"
|
||||
"github.com/ledgerwatch/turbo-geth/p2p/enode"
|
||||
"github.com/ledgerwatch/turbo-geth/p2p/enr"
|
||||
"github.com/ledgerwatch/turbo-geth/p2p/netutil"
|
||||
"github.com/ledgerwatch/turbo-geth/rlp"
|
||||
)
|
||||
@ -243,7 +243,7 @@ func (t *UDPv4) sendPing(toid enode.ID, toaddr *net.UDPAddr, callback func()) *r
|
||||
})
|
||||
// Send the packet.
|
||||
t.localNode.UDPContact(toaddr)
|
||||
t.write(toaddr, toid, req.Name(), packet)
|
||||
t.write(toaddr, toid, req.Name(), packet) //nolint:errcheck
|
||||
return rm
|
||||
}
|
||||
|
||||
@ -320,10 +320,12 @@ func (t *UDPv4) findnode(toid enode.ID, toaddr *net.UDPAddr, target v4wire.Pubke
|
||||
}
|
||||
return true, nreceived >= bucketSize
|
||||
})
|
||||
t.send(toaddr, toid, &v4wire.Findnode{
|
||||
if _, err := t.send(toaddr, toid, &v4wire.Findnode{
|
||||
Target: target,
|
||||
Expiration: uint64(time.Now().Add(expiration).Unix()),
|
||||
})
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nodes, <-rm.errc
|
||||
}
|
||||
|
||||
@ -347,8 +349,12 @@ func (t *UDPv4) RequestENR(n *enode.Node) (*enode.Node, error) {
|
||||
return matched, matched
|
||||
})
|
||||
// Send the packet and wait for the reply.
|
||||
t.write(addr, n.ID(), req.Name(), packet)
|
||||
if err := <-rm.errc; err != nil {
|
||||
|
||||
err = t.write(addr, n.ID(), req.Name(), packet)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = <-rm.errc; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Verify the response record.
|
||||
@ -489,6 +495,7 @@ func (t *UDPv4) loop() {
|
||||
}
|
||||
}
|
||||
|
||||
//nolint:unparam
|
||||
func (t *UDPv4) send(toaddr *net.UDPAddr, toid enode.ID, req v4wire.Packet) ([]byte, error) {
|
||||
packet, hash, err := v4wire.Encode(t.priv, req)
|
||||
if err != nil {
|
||||
@ -652,6 +659,8 @@ func (t *UDPv4) handlePing(h *packetHandlerV4, from *net.UDPAddr, fromID enode.I
|
||||
|
||||
// Reply.
|
||||
seq, _ := rlp.EncodeToBytes(t.localNode.Node().Seq())
|
||||
|
||||
//nolint:errcheck
|
||||
t.send(from, fromID, &v4wire.Pong{
|
||||
To: v4wire.NewEndpoint(from, req.From.TCP),
|
||||
ReplyTok: mac,
|
||||
@ -767,6 +776,7 @@ func (t *UDPv4) verifyENRRequest(h *packetHandlerV4, from *net.UDPAddr, fromID e
|
||||
}
|
||||
|
||||
func (t *UDPv4) handleENRRequest(h *packetHandlerV4, from *net.UDPAddr, fromID enode.ID, mac []byte) {
|
||||
//nolint:errcheck
|
||||
t.send(from, fromID, &v4wire.ENRResponse{
|
||||
ReplyTok: mac,
|
||||
Record: *t.localNode.Node().Record(),
|
||||
|
@ -30,14 +30,11 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/ledgerwatch/turbo-geth/common"
|
||||
"github.com/ledgerwatch/turbo-geth/crypto"
|
||||
"github.com/ledgerwatch/turbo-geth/internal/testlog"
|
||||
"github.com/ledgerwatch/turbo-geth/log"
|
||||
"github.com/ledgerwatch/turbo-geth/p2p/discover/v4wire"
|
||||
"github.com/ledgerwatch/turbo-geth/p2p/enode"
|
||||
"github.com/ledgerwatch/turbo-geth/p2p/enr"
|
||||
"github.com/ledgerwatch/turbo-geth/rlp"
|
||||
)
|
||||
|
||||
// shared test variables
|
||||
|
@ -27,11 +27,11 @@ import (
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/math"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
"github.com/ethereum/go-ethereum/p2p/enr"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
"github.com/ledgerwatch/turbo-geth/common/math"
|
||||
"github.com/ledgerwatch/turbo-geth/crypto"
|
||||
"github.com/ledgerwatch/turbo-geth/p2p/enode"
|
||||
"github.com/ledgerwatch/turbo-geth/p2p/enr"
|
||||
"github.com/ledgerwatch/turbo-geth/rlp"
|
||||
)
|
||||
|
||||
// RPC packet types
|
||||
@ -192,7 +192,7 @@ func seqFromTail(tail []rlp.RawValue) uint64 {
|
||||
return 0
|
||||
}
|
||||
var seq uint64
|
||||
rlp.DecodeBytes(tail[0], &seq)
|
||||
rlp.DecodeBytes(tail[0], &seq) //nolint:errcheck
|
||||
return seq
|
||||
}
|
||||
|
||||
@ -254,7 +254,7 @@ func Encode(priv *ecdsa.PrivateKey, req Packet) (packet, hash []byte, err error)
|
||||
b := new(bytes.Buffer)
|
||||
b.Write(headSpace)
|
||||
b.WriteByte(req.Kind())
|
||||
if err := rlp.Encode(b, req); err != nil {
|
||||
if err = rlp.Encode(b, req); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
packet = b.Bytes()
|
||||
|
@ -23,9 +23,9 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
"github.com/ledgerwatch/turbo-geth/common"
|
||||
"github.com/ledgerwatch/turbo-geth/crypto"
|
||||
"github.com/ledgerwatch/turbo-geth/rlp"
|
||||
)
|
||||
|
||||
// EIP-8 test vectors.
|
||||
|
@ -1,880 +0,0 @@
|
||||
// Copyright 2020 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/>.
|
||||
|
||||
package nodestate
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"reflect"
|
||||
"sync"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/mclock"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/metrics"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
"github.com/ethereum/go-ethereum/p2p/enr"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
)
|
||||
|
||||
type (
|
||||
// NodeStateMachine connects different system components operating on subsets of
|
||||
// network nodes. Node states are represented by 64 bit vectors with each bit assigned
|
||||
// to a state flag. Each state flag has a descriptor structure and the mapping is
|
||||
// created automatically. It is possible to subscribe to subsets of state flags and
|
||||
// receive a callback if one of the nodes has a relevant state flag changed.
|
||||
// Callbacks can also modify further flags of the same node or other nodes. State
|
||||
// updates only return after all immediate effects throughout the system have happened
|
||||
// (deadlocks should be avoided by design of the implemented state logic). The caller
|
||||
// can also add timeouts assigned to a certain node and a subset of state flags.
|
||||
// If the timeout elapses, the flags are reset. If all relevant flags are reset then
|
||||
// the timer is dropped. State flags with no timeout are persisted in the database
|
||||
// if the flag descriptor enables saving. If a node has no state flags set at any
|
||||
// moment then it is discarded.
|
||||
//
|
||||
// Extra node fields can also be registered so system components can also store more
|
||||
// complex state for each node that is relevant to them, without creating a custom
|
||||
// peer set. Fields can be shared across multiple components if they all know the
|
||||
// field ID. Subscription to fields is also possible. Persistent fields should have
|
||||
// an encoder and a decoder function.
|
||||
NodeStateMachine struct {
|
||||
started, stopped bool
|
||||
lock sync.Mutex
|
||||
clock mclock.Clock
|
||||
db ethdb.KeyValueStore
|
||||
dbNodeKey []byte
|
||||
nodes map[enode.ID]*nodeInfo
|
||||
offlineCallbackList []offlineCallback
|
||||
|
||||
// Registered state flags or fields. Modifications are allowed
|
||||
// only when the node state machine has not been started.
|
||||
setup *Setup
|
||||
fields []*fieldInfo
|
||||
saveFlags bitMask
|
||||
|
||||
// Installed callbacks. Modifications are allowed only when the
|
||||
// node state machine has not been started.
|
||||
stateSubs []stateSub
|
||||
|
||||
// Testing hooks, only for testing purposes.
|
||||
saveNodeHook func(*nodeInfo)
|
||||
}
|
||||
|
||||
// Flags represents a set of flags from a certain setup
|
||||
Flags struct {
|
||||
mask bitMask
|
||||
setup *Setup
|
||||
}
|
||||
|
||||
// Field represents a field from a certain setup
|
||||
Field struct {
|
||||
index int
|
||||
setup *Setup
|
||||
}
|
||||
|
||||
// flagDefinition describes a node state flag. Each registered instance is automatically
|
||||
// mapped to a bit of the 64 bit node states.
|
||||
// If persistent is true then the node is saved when state machine is shutdown.
|
||||
flagDefinition struct {
|
||||
name string
|
||||
persistent bool
|
||||
}
|
||||
|
||||
// fieldDefinition describes an optional node field of the given type. The contents
|
||||
// of the field are only retained for each node as long as at least one of the
|
||||
// state flags is set.
|
||||
fieldDefinition struct {
|
||||
name string
|
||||
ftype reflect.Type
|
||||
encode func(interface{}) ([]byte, error)
|
||||
decode func([]byte) (interface{}, error)
|
||||
}
|
||||
|
||||
// stateSetup contains the list of flags and fields used by the application
|
||||
Setup struct {
|
||||
Version uint
|
||||
flags []flagDefinition
|
||||
fields []fieldDefinition
|
||||
}
|
||||
|
||||
// bitMask describes a node state or state mask. It represents a subset
|
||||
// of node flags with each bit assigned to a flag index (LSB represents flag 0).
|
||||
bitMask uint64
|
||||
|
||||
// StateCallback is a subscription callback which is called when one of the
|
||||
// state flags that is included in the subscription state mask is changed.
|
||||
// Note: oldState and newState are also masked with the subscription mask so only
|
||||
// the relevant bits are included.
|
||||
StateCallback func(n *enode.Node, oldState, newState Flags)
|
||||
|
||||
// FieldCallback is a subscription callback which is called when the value of
|
||||
// a specific field is changed.
|
||||
FieldCallback func(n *enode.Node, state Flags, oldValue, newValue interface{})
|
||||
|
||||
// nodeInfo contains node state, fields and state timeouts
|
||||
nodeInfo struct {
|
||||
node *enode.Node
|
||||
state bitMask
|
||||
timeouts []*nodeStateTimeout
|
||||
fields []interface{}
|
||||
db, dirty bool
|
||||
}
|
||||
|
||||
nodeInfoEnc struct {
|
||||
Enr enr.Record
|
||||
Version uint
|
||||
State bitMask
|
||||
Fields [][]byte
|
||||
}
|
||||
|
||||
stateSub struct {
|
||||
mask bitMask
|
||||
callback StateCallback
|
||||
}
|
||||
|
||||
nodeStateTimeout struct {
|
||||
mask bitMask
|
||||
timer mclock.Timer
|
||||
}
|
||||
|
||||
fieldInfo struct {
|
||||
fieldDefinition
|
||||
subs []FieldCallback
|
||||
}
|
||||
|
||||
offlineCallback struct {
|
||||
node *enode.Node
|
||||
state bitMask
|
||||
fields []interface{}
|
||||
}
|
||||
)
|
||||
|
||||
// offlineState is a special state that is assumed to be set before a node is loaded from
|
||||
// the database and after it is shut down.
|
||||
const offlineState = bitMask(1)
|
||||
|
||||
// NewFlag creates a new node state flag
|
||||
func (s *Setup) NewFlag(name string) Flags {
|
||||
if s.flags == nil {
|
||||
s.flags = []flagDefinition{{name: "offline"}}
|
||||
}
|
||||
f := Flags{mask: bitMask(1) << uint(len(s.flags)), setup: s}
|
||||
s.flags = append(s.flags, flagDefinition{name: name})
|
||||
return f
|
||||
}
|
||||
|
||||
// NewPersistentFlag creates a new persistent node state flag
|
||||
func (s *Setup) NewPersistentFlag(name string) Flags {
|
||||
if s.flags == nil {
|
||||
s.flags = []flagDefinition{{name: "offline"}}
|
||||
}
|
||||
f := Flags{mask: bitMask(1) << uint(len(s.flags)), setup: s}
|
||||
s.flags = append(s.flags, flagDefinition{name: name, persistent: true})
|
||||
return f
|
||||
}
|
||||
|
||||
// OfflineFlag returns the system-defined offline flag belonging to the given setup
|
||||
func (s *Setup) OfflineFlag() Flags {
|
||||
return Flags{mask: offlineState, setup: s}
|
||||
}
|
||||
|
||||
// NewField creates a new node state field
|
||||
func (s *Setup) NewField(name string, ftype reflect.Type) Field {
|
||||
f := Field{index: len(s.fields), setup: s}
|
||||
s.fields = append(s.fields, fieldDefinition{
|
||||
name: name,
|
||||
ftype: ftype,
|
||||
})
|
||||
return f
|
||||
}
|
||||
|
||||
// NewPersistentField creates a new persistent node field
|
||||
func (s *Setup) NewPersistentField(name string, ftype reflect.Type, encode func(interface{}) ([]byte, error), decode func([]byte) (interface{}, error)) Field {
|
||||
f := Field{index: len(s.fields), setup: s}
|
||||
s.fields = append(s.fields, fieldDefinition{
|
||||
name: name,
|
||||
ftype: ftype,
|
||||
encode: encode,
|
||||
decode: decode,
|
||||
})
|
||||
return f
|
||||
}
|
||||
|
||||
// flagOp implements binary flag operations and also checks whether the operands belong to the same setup
|
||||
func flagOp(a, b Flags, trueIfA, trueIfB, trueIfBoth bool) Flags {
|
||||
if a.setup == nil {
|
||||
if a.mask != 0 {
|
||||
panic("Node state flags have no setup reference")
|
||||
}
|
||||
a.setup = b.setup
|
||||
}
|
||||
if b.setup == nil {
|
||||
if b.mask != 0 {
|
||||
panic("Node state flags have no setup reference")
|
||||
}
|
||||
b.setup = a.setup
|
||||
}
|
||||
if a.setup != b.setup {
|
||||
panic("Node state flags belong to a different setup")
|
||||
}
|
||||
res := Flags{setup: a.setup}
|
||||
if trueIfA {
|
||||
res.mask |= a.mask & ^b.mask
|
||||
}
|
||||
if trueIfB {
|
||||
res.mask |= b.mask & ^a.mask
|
||||
}
|
||||
if trueIfBoth {
|
||||
res.mask |= a.mask & b.mask
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// And returns the set of flags present in both a and b
|
||||
func (a Flags) And(b Flags) Flags { return flagOp(a, b, false, false, true) }
|
||||
|
||||
// AndNot returns the set of flags present in a but not in b
|
||||
func (a Flags) AndNot(b Flags) Flags { return flagOp(a, b, true, false, false) }
|
||||
|
||||
// Or returns the set of flags present in either a or b
|
||||
func (a Flags) Or(b Flags) Flags { return flagOp(a, b, true, true, true) }
|
||||
|
||||
// Xor returns the set of flags present in either a or b but not both
|
||||
func (a Flags) Xor(b Flags) Flags { return flagOp(a, b, true, true, false) }
|
||||
|
||||
// HasAll returns true if b is a subset of a
|
||||
func (a Flags) HasAll(b Flags) bool { return flagOp(a, b, false, true, false).mask == 0 }
|
||||
|
||||
// HasNone returns true if a and b have no shared flags
|
||||
func (a Flags) HasNone(b Flags) bool { return flagOp(a, b, false, false, true).mask == 0 }
|
||||
|
||||
// Equals returns true if a and b have the same flags set
|
||||
func (a Flags) Equals(b Flags) bool { return flagOp(a, b, true, true, false).mask == 0 }
|
||||
|
||||
// IsEmpty returns true if a has no flags set
|
||||
func (a Flags) IsEmpty() bool { return a.mask == 0 }
|
||||
|
||||
// MergeFlags merges multiple sets of state flags
|
||||
func MergeFlags(list ...Flags) Flags {
|
||||
if len(list) == 0 {
|
||||
return Flags{}
|
||||
}
|
||||
res := list[0]
|
||||
for i := 1; i < len(list); i++ {
|
||||
res = res.Or(list[i])
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// String returns a list of the names of the flags specified in the bit mask
|
||||
func (f Flags) String() string {
|
||||
if f.mask == 0 {
|
||||
return "[]"
|
||||
}
|
||||
s := "["
|
||||
comma := false
|
||||
for index, flag := range f.setup.flags {
|
||||
if f.mask&(bitMask(1)<<uint(index)) != 0 {
|
||||
if comma {
|
||||
s = s + ", "
|
||||
}
|
||||
s = s + flag.name
|
||||
comma = true
|
||||
}
|
||||
}
|
||||
s = s + "]"
|
||||
return s
|
||||
}
|
||||
|
||||
// NewNodeStateMachine creates a new node state machine.
|
||||
// If db is not nil then the node states, fields and active timeouts are persisted.
|
||||
// Persistence can be enabled or disabled for each state flag and field.
|
||||
func NewNodeStateMachine(db ethdb.KeyValueStore, dbKey []byte, clock mclock.Clock, setup *Setup) *NodeStateMachine {
|
||||
if setup.flags == nil {
|
||||
panic("No state flags defined")
|
||||
}
|
||||
if len(setup.flags) > 8*int(unsafe.Sizeof(bitMask(0))) {
|
||||
panic("Too many node state flags")
|
||||
}
|
||||
ns := &NodeStateMachine{
|
||||
db: db,
|
||||
dbNodeKey: dbKey,
|
||||
clock: clock,
|
||||
setup: setup,
|
||||
nodes: make(map[enode.ID]*nodeInfo),
|
||||
fields: make([]*fieldInfo, len(setup.fields)),
|
||||
}
|
||||
stateNameMap := make(map[string]int)
|
||||
for index, flag := range setup.flags {
|
||||
if _, ok := stateNameMap[flag.name]; ok {
|
||||
panic("Node state flag name collision")
|
||||
}
|
||||
stateNameMap[flag.name] = index
|
||||
if flag.persistent {
|
||||
ns.saveFlags |= bitMask(1) << uint(index)
|
||||
}
|
||||
}
|
||||
fieldNameMap := make(map[string]int)
|
||||
for index, field := range setup.fields {
|
||||
if _, ok := fieldNameMap[field.name]; ok {
|
||||
panic("Node field name collision")
|
||||
}
|
||||
ns.fields[index] = &fieldInfo{fieldDefinition: field}
|
||||
fieldNameMap[field.name] = index
|
||||
}
|
||||
return ns
|
||||
}
|
||||
|
||||
// stateMask checks whether the set of flags belongs to the same setup and returns its internal bit mask
|
||||
func (ns *NodeStateMachine) stateMask(flags Flags) bitMask {
|
||||
if flags.setup != ns.setup && flags.mask != 0 {
|
||||
panic("Node state flags belong to a different setup")
|
||||
}
|
||||
return flags.mask
|
||||
}
|
||||
|
||||
// fieldIndex checks whether the field belongs to the same setup and returns its internal index
|
||||
func (ns *NodeStateMachine) fieldIndex(field Field) int {
|
||||
if field.setup != ns.setup {
|
||||
panic("Node field belongs to a different setup")
|
||||
}
|
||||
return field.index
|
||||
}
|
||||
|
||||
// SubscribeState adds a node state subscription. The callback is called while the state
|
||||
// machine mutex is not held and it is allowed to make further state updates. All immediate
|
||||
// changes throughout the system are processed in the same thread/goroutine. It is the
|
||||
// responsibility of the implemented state logic to avoid deadlocks caused by the callbacks,
|
||||
// infinite toggling of flags or hazardous/non-deterministic state changes.
|
||||
// State subscriptions should be installed before loading the node database or making the
|
||||
// first state update.
|
||||
func (ns *NodeStateMachine) SubscribeState(flags Flags, callback StateCallback) {
|
||||
ns.lock.Lock()
|
||||
defer ns.lock.Unlock()
|
||||
|
||||
if ns.started {
|
||||
panic("state machine already started")
|
||||
}
|
||||
ns.stateSubs = append(ns.stateSubs, stateSub{ns.stateMask(flags), callback})
|
||||
}
|
||||
|
||||
// SubscribeField adds a node field subscription. Same rules apply as for SubscribeState.
|
||||
func (ns *NodeStateMachine) SubscribeField(field Field, callback FieldCallback) {
|
||||
ns.lock.Lock()
|
||||
defer ns.lock.Unlock()
|
||||
|
||||
if ns.started {
|
||||
panic("state machine already started")
|
||||
}
|
||||
f := ns.fields[ns.fieldIndex(field)]
|
||||
f.subs = append(f.subs, callback)
|
||||
}
|
||||
|
||||
// newNode creates a new nodeInfo
|
||||
func (ns *NodeStateMachine) newNode(n *enode.Node) *nodeInfo {
|
||||
return &nodeInfo{node: n, fields: make([]interface{}, len(ns.fields))}
|
||||
}
|
||||
|
||||
// checkStarted checks whether the state machine has already been started and panics otherwise.
|
||||
func (ns *NodeStateMachine) checkStarted() {
|
||||
if !ns.started {
|
||||
panic("state machine not started yet")
|
||||
}
|
||||
}
|
||||
|
||||
// Start starts the state machine, enabling state and field operations and disabling
|
||||
// further subscriptions.
|
||||
func (ns *NodeStateMachine) Start() {
|
||||
ns.lock.Lock()
|
||||
if ns.started {
|
||||
panic("state machine already started")
|
||||
}
|
||||
ns.started = true
|
||||
if ns.db != nil {
|
||||
ns.loadFromDb()
|
||||
}
|
||||
ns.lock.Unlock()
|
||||
ns.offlineCallbacks(true)
|
||||
}
|
||||
|
||||
// Stop stops the state machine and saves its state if a database was supplied
|
||||
func (ns *NodeStateMachine) Stop() {
|
||||
ns.lock.Lock()
|
||||
for _, node := range ns.nodes {
|
||||
fields := make([]interface{}, len(node.fields))
|
||||
copy(fields, node.fields)
|
||||
ns.offlineCallbackList = append(ns.offlineCallbackList, offlineCallback{node.node, node.state, fields})
|
||||
}
|
||||
ns.stopped = true
|
||||
if ns.db != nil {
|
||||
ns.saveToDb()
|
||||
ns.lock.Unlock()
|
||||
} else {
|
||||
ns.lock.Unlock()
|
||||
}
|
||||
ns.offlineCallbacks(false)
|
||||
}
|
||||
|
||||
// loadFromDb loads persisted node states from the database
|
||||
func (ns *NodeStateMachine) loadFromDb() {
|
||||
it := ns.db.NewIterator(ns.dbNodeKey, nil)
|
||||
for it.Next() {
|
||||
var id enode.ID
|
||||
if len(it.Key()) != len(ns.dbNodeKey)+len(id) {
|
||||
log.Error("Node state db entry with invalid length", "found", len(it.Key()), "expected", len(ns.dbNodeKey)+len(id))
|
||||
continue
|
||||
}
|
||||
copy(id[:], it.Key()[len(ns.dbNodeKey):])
|
||||
ns.decodeNode(id, it.Value())
|
||||
}
|
||||
}
|
||||
|
||||
type dummyIdentity enode.ID
|
||||
|
||||
func (id dummyIdentity) Verify(r *enr.Record, sig []byte) error { return nil }
|
||||
func (id dummyIdentity) NodeAddr(r *enr.Record) []byte { return id[:] }
|
||||
|
||||
// decodeNode decodes a node database entry and adds it to the node set if successful
|
||||
func (ns *NodeStateMachine) decodeNode(id enode.ID, data []byte) {
|
||||
var enc nodeInfoEnc
|
||||
if err := rlp.DecodeBytes(data, &enc); err != nil {
|
||||
log.Error("Failed to decode node info", "id", id, "error", err)
|
||||
return
|
||||
}
|
||||
n, _ := enode.New(dummyIdentity(id), &enc.Enr)
|
||||
node := ns.newNode(n)
|
||||
node.db = true
|
||||
|
||||
if enc.Version != ns.setup.Version {
|
||||
log.Debug("Removing stored node with unknown version", "current", ns.setup.Version, "stored", enc.Version)
|
||||
ns.deleteNode(id)
|
||||
return
|
||||
}
|
||||
if len(enc.Fields) > len(ns.setup.fields) {
|
||||
log.Error("Invalid node field count", "id", id, "stored", len(enc.Fields))
|
||||
return
|
||||
}
|
||||
// Resolve persisted node fields
|
||||
for i, encField := range enc.Fields {
|
||||
if len(encField) == 0 {
|
||||
continue
|
||||
}
|
||||
if decode := ns.fields[i].decode; decode != nil {
|
||||
if field, err := decode(encField); err == nil {
|
||||
node.fields[i] = field
|
||||
} else {
|
||||
log.Error("Failed to decode node field", "id", id, "field name", ns.fields[i].name, "error", err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
log.Error("Cannot decode node field", "id", id, "field name", ns.fields[i].name)
|
||||
return
|
||||
}
|
||||
}
|
||||
// It's a compatible node record, add it to set.
|
||||
ns.nodes[id] = node
|
||||
node.state = enc.State
|
||||
fields := make([]interface{}, len(node.fields))
|
||||
copy(fields, node.fields)
|
||||
ns.offlineCallbackList = append(ns.offlineCallbackList, offlineCallback{node.node, node.state, fields})
|
||||
log.Debug("Loaded node state", "id", id, "state", Flags{mask: enc.State, setup: ns.setup})
|
||||
}
|
||||
|
||||
// saveNode saves the given node info to the database
|
||||
func (ns *NodeStateMachine) saveNode(id enode.ID, node *nodeInfo) error {
|
||||
if ns.db == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
storedState := node.state & ns.saveFlags
|
||||
for _, t := range node.timeouts {
|
||||
storedState &= ^t.mask
|
||||
}
|
||||
if storedState == 0 {
|
||||
if node.db {
|
||||
node.db = false
|
||||
ns.deleteNode(id)
|
||||
}
|
||||
node.dirty = false
|
||||
return nil
|
||||
}
|
||||
|
||||
enc := nodeInfoEnc{
|
||||
Enr: *node.node.Record(),
|
||||
Version: ns.setup.Version,
|
||||
State: storedState,
|
||||
Fields: make([][]byte, len(ns.fields)),
|
||||
}
|
||||
log.Debug("Saved node state", "id", id, "state", Flags{mask: enc.State, setup: ns.setup})
|
||||
lastIndex := -1
|
||||
for i, f := range node.fields {
|
||||
if f == nil {
|
||||
continue
|
||||
}
|
||||
encode := ns.fields[i].encode
|
||||
if encode == nil {
|
||||
continue
|
||||
}
|
||||
blob, err := encode(f)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
enc.Fields[i] = blob
|
||||
lastIndex = i
|
||||
}
|
||||
enc.Fields = enc.Fields[:lastIndex+1]
|
||||
data, err := rlp.EncodeToBytes(&enc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := ns.db.Put(append(ns.dbNodeKey, id[:]...), data); err != nil {
|
||||
return err
|
||||
}
|
||||
node.dirty, node.db = false, true
|
||||
|
||||
if ns.saveNodeHook != nil {
|
||||
ns.saveNodeHook(node)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// deleteNode removes a node info from the database
|
||||
func (ns *NodeStateMachine) deleteNode(id enode.ID) {
|
||||
ns.db.Delete(append(ns.dbNodeKey, id[:]...))
|
||||
}
|
||||
|
||||
// saveToDb saves the persistent flags and fields of all nodes that have been changed
|
||||
func (ns *NodeStateMachine) saveToDb() {
|
||||
for id, node := range ns.nodes {
|
||||
if node.dirty {
|
||||
err := ns.saveNode(id, node)
|
||||
if err != nil {
|
||||
log.Error("Failed to save node", "id", id, "error", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// updateEnode updates the enode entry belonging to the given node if it already exists
|
||||
func (ns *NodeStateMachine) updateEnode(n *enode.Node) (enode.ID, *nodeInfo) {
|
||||
id := n.ID()
|
||||
node := ns.nodes[id]
|
||||
if node != nil && n.Seq() > node.node.Seq() {
|
||||
node.node = n
|
||||
}
|
||||
return id, node
|
||||
}
|
||||
|
||||
// Persist saves the persistent state and fields of the given node immediately
|
||||
func (ns *NodeStateMachine) Persist(n *enode.Node) error {
|
||||
ns.lock.Lock()
|
||||
defer ns.lock.Unlock()
|
||||
|
||||
ns.checkStarted()
|
||||
if id, node := ns.updateEnode(n); node != nil && node.dirty {
|
||||
err := ns.saveNode(id, node)
|
||||
if err != nil {
|
||||
log.Error("Failed to save node", "id", id, "error", err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetState updates the given node state flags and processes all resulting callbacks.
|
||||
// It only returns after all subsequent immediate changes (including those changed by the
|
||||
// callbacks) have been processed. If a flag with a timeout is set again, the operation
|
||||
// removes or replaces the existing timeout.
|
||||
func (ns *NodeStateMachine) SetState(n *enode.Node, setFlags, resetFlags Flags, timeout time.Duration) {
|
||||
ns.lock.Lock()
|
||||
ns.checkStarted()
|
||||
if ns.stopped {
|
||||
ns.lock.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
set, reset := ns.stateMask(setFlags), ns.stateMask(resetFlags)
|
||||
id, node := ns.updateEnode(n)
|
||||
if node == nil {
|
||||
if set == 0 {
|
||||
ns.lock.Unlock()
|
||||
return
|
||||
}
|
||||
node = ns.newNode(n)
|
||||
ns.nodes[id] = node
|
||||
}
|
||||
oldState := node.state
|
||||
newState := (node.state & (^reset)) | set
|
||||
changed := oldState ^ newState
|
||||
node.state = newState
|
||||
|
||||
// Remove the timeout callbacks for all reset and set flags,
|
||||
// even they are not existent(it's noop).
|
||||
ns.removeTimeouts(node, set|reset)
|
||||
|
||||
// Register the timeout callback if the new state is not empty
|
||||
// and timeout itself is required.
|
||||
if timeout != 0 && newState != 0 {
|
||||
ns.addTimeout(n, set, timeout)
|
||||
}
|
||||
if newState == oldState {
|
||||
ns.lock.Unlock()
|
||||
return
|
||||
}
|
||||
if newState == 0 {
|
||||
delete(ns.nodes, id)
|
||||
if node.db {
|
||||
ns.deleteNode(id)
|
||||
}
|
||||
} else {
|
||||
if changed&ns.saveFlags != 0 {
|
||||
node.dirty = true
|
||||
}
|
||||
}
|
||||
ns.lock.Unlock()
|
||||
// call state update subscription callbacks without holding the mutex
|
||||
for _, sub := range ns.stateSubs {
|
||||
if changed&sub.mask != 0 {
|
||||
sub.callback(n, Flags{mask: oldState & sub.mask, setup: ns.setup}, Flags{mask: newState & sub.mask, setup: ns.setup})
|
||||
}
|
||||
}
|
||||
if newState == 0 {
|
||||
// call field subscriptions for discarded fields
|
||||
for i, v := range node.fields {
|
||||
if v != nil {
|
||||
f := ns.fields[i]
|
||||
if len(f.subs) > 0 {
|
||||
for _, cb := range f.subs {
|
||||
cb(n, Flags{setup: ns.setup}, v, nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// offlineCallbacks calls state update callbacks at startup or shutdown
|
||||
func (ns *NodeStateMachine) offlineCallbacks(start bool) {
|
||||
for _, cb := range ns.offlineCallbackList {
|
||||
for _, sub := range ns.stateSubs {
|
||||
offState := offlineState & sub.mask
|
||||
onState := cb.state & sub.mask
|
||||
if offState != onState {
|
||||
if start {
|
||||
sub.callback(cb.node, Flags{mask: offState, setup: ns.setup}, Flags{mask: onState, setup: ns.setup})
|
||||
} else {
|
||||
sub.callback(cb.node, Flags{mask: onState, setup: ns.setup}, Flags{mask: offState, setup: ns.setup})
|
||||
}
|
||||
}
|
||||
}
|
||||
for i, f := range cb.fields {
|
||||
if f != nil && ns.fields[i].subs != nil {
|
||||
for _, fsub := range ns.fields[i].subs {
|
||||
if start {
|
||||
fsub(cb.node, Flags{mask: offlineState, setup: ns.setup}, nil, f)
|
||||
} else {
|
||||
fsub(cb.node, Flags{mask: offlineState, setup: ns.setup}, f, nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ns.offlineCallbackList = nil
|
||||
}
|
||||
|
||||
// AddTimeout adds a node state timeout associated to the given state flag(s).
|
||||
// After the specified time interval, the relevant states will be reset.
|
||||
func (ns *NodeStateMachine) AddTimeout(n *enode.Node, flags Flags, timeout time.Duration) {
|
||||
ns.lock.Lock()
|
||||
defer ns.lock.Unlock()
|
||||
|
||||
ns.checkStarted()
|
||||
if ns.stopped {
|
||||
return
|
||||
}
|
||||
ns.addTimeout(n, ns.stateMask(flags), timeout)
|
||||
}
|
||||
|
||||
// addTimeout adds a node state timeout associated to the given state flag(s).
|
||||
func (ns *NodeStateMachine) addTimeout(n *enode.Node, mask bitMask, timeout time.Duration) {
|
||||
_, node := ns.updateEnode(n)
|
||||
if node == nil {
|
||||
return
|
||||
}
|
||||
mask &= node.state
|
||||
if mask == 0 {
|
||||
return
|
||||
}
|
||||
ns.removeTimeouts(node, mask)
|
||||
t := &nodeStateTimeout{mask: mask}
|
||||
t.timer = ns.clock.AfterFunc(timeout, func() {
|
||||
ns.SetState(n, Flags{}, Flags{mask: t.mask, setup: ns.setup}, 0)
|
||||
})
|
||||
node.timeouts = append(node.timeouts, t)
|
||||
if mask&ns.saveFlags != 0 {
|
||||
node.dirty = true
|
||||
}
|
||||
}
|
||||
|
||||
// removeTimeout removes node state timeouts associated to the given state flag(s).
|
||||
// If a timeout was associated to multiple flags which are not all included in the
|
||||
// specified remove mask then only the included flags are de-associated and the timer
|
||||
// stays active.
|
||||
func (ns *NodeStateMachine) removeTimeouts(node *nodeInfo, mask bitMask) {
|
||||
for i := 0; i < len(node.timeouts); i++ {
|
||||
t := node.timeouts[i]
|
||||
match := t.mask & mask
|
||||
if match == 0 {
|
||||
continue
|
||||
}
|
||||
t.mask -= match
|
||||
if t.mask != 0 {
|
||||
continue
|
||||
}
|
||||
t.timer.Stop()
|
||||
node.timeouts[i] = node.timeouts[len(node.timeouts)-1]
|
||||
node.timeouts = node.timeouts[:len(node.timeouts)-1]
|
||||
i--
|
||||
if match&ns.saveFlags != 0 {
|
||||
node.dirty = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GetField retrieves the given field of the given node
|
||||
func (ns *NodeStateMachine) GetField(n *enode.Node, field Field) interface{} {
|
||||
ns.lock.Lock()
|
||||
defer ns.lock.Unlock()
|
||||
|
||||
ns.checkStarted()
|
||||
if ns.stopped {
|
||||
return nil
|
||||
}
|
||||
if _, node := ns.updateEnode(n); node != nil {
|
||||
return node.fields[ns.fieldIndex(field)]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetField sets the given field of the given node
|
||||
func (ns *NodeStateMachine) SetField(n *enode.Node, field Field, value interface{}) error {
|
||||
ns.lock.Lock()
|
||||
ns.checkStarted()
|
||||
if ns.stopped {
|
||||
ns.lock.Unlock()
|
||||
return nil
|
||||
}
|
||||
_, node := ns.updateEnode(n)
|
||||
if node == nil {
|
||||
ns.lock.Unlock()
|
||||
return nil
|
||||
}
|
||||
fieldIndex := ns.fieldIndex(field)
|
||||
f := ns.fields[fieldIndex]
|
||||
if value != nil && reflect.TypeOf(value) != f.ftype {
|
||||
log.Error("Invalid field type", "type", reflect.TypeOf(value), "required", f.ftype)
|
||||
ns.lock.Unlock()
|
||||
return errors.New("invalid field type")
|
||||
}
|
||||
oldValue := node.fields[fieldIndex]
|
||||
if value == oldValue {
|
||||
ns.lock.Unlock()
|
||||
return nil
|
||||
}
|
||||
node.fields[fieldIndex] = value
|
||||
if f.encode != nil {
|
||||
node.dirty = true
|
||||
}
|
||||
|
||||
state := node.state
|
||||
ns.lock.Unlock()
|
||||
if len(f.subs) > 0 {
|
||||
for _, cb := range f.subs {
|
||||
cb(n, Flags{mask: state, setup: ns.setup}, oldValue, value)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ForEach calls the callback for each node having all of the required and none of the
|
||||
// disabled flags set
|
||||
func (ns *NodeStateMachine) ForEach(requireFlags, disableFlags Flags, cb func(n *enode.Node, state Flags)) {
|
||||
ns.lock.Lock()
|
||||
ns.checkStarted()
|
||||
type callback struct {
|
||||
node *enode.Node
|
||||
state bitMask
|
||||
}
|
||||
require, disable := ns.stateMask(requireFlags), ns.stateMask(disableFlags)
|
||||
var callbacks []callback
|
||||
for _, node := range ns.nodes {
|
||||
if node.state&require == require && node.state&disable == 0 {
|
||||
callbacks = append(callbacks, callback{node.node, node.state & (require | disable)})
|
||||
}
|
||||
}
|
||||
ns.lock.Unlock()
|
||||
for _, c := range callbacks {
|
||||
cb(c.node, Flags{mask: c.state, setup: ns.setup})
|
||||
}
|
||||
}
|
||||
|
||||
// GetNode returns the enode currently associated with the given ID
|
||||
func (ns *NodeStateMachine) GetNode(id enode.ID) *enode.Node {
|
||||
ns.lock.Lock()
|
||||
defer ns.lock.Unlock()
|
||||
|
||||
ns.checkStarted()
|
||||
if node := ns.nodes[id]; node != nil {
|
||||
return node.node
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddLogMetrics adds logging and/or metrics for nodes entering, exiting and currently
|
||||
// being in a given set specified by required and disabled state flags
|
||||
func (ns *NodeStateMachine) AddLogMetrics(requireFlags, disableFlags Flags, name string, inMeter, outMeter metrics.Meter, gauge metrics.Gauge) {
|
||||
var count int64
|
||||
ns.SubscribeState(requireFlags.Or(disableFlags), func(n *enode.Node, oldState, newState Flags) {
|
||||
oldMatch := oldState.HasAll(requireFlags) && oldState.HasNone(disableFlags)
|
||||
newMatch := newState.HasAll(requireFlags) && newState.HasNone(disableFlags)
|
||||
if newMatch == oldMatch {
|
||||
return
|
||||
}
|
||||
|
||||
if newMatch {
|
||||
count++
|
||||
if name != "" {
|
||||
log.Debug("Node entered", "set", name, "id", n.ID(), "count", count)
|
||||
}
|
||||
if inMeter != nil {
|
||||
inMeter.Mark(1)
|
||||
}
|
||||
} else {
|
||||
count--
|
||||
if name != "" {
|
||||
log.Debug("Node left", "set", name, "id", n.ID(), "count", count)
|
||||
}
|
||||
if outMeter != nil {
|
||||
outMeter.Mark(1)
|
||||
}
|
||||
}
|
||||
if gauge != nil {
|
||||
gauge.Update(count)
|
||||
}
|
||||
})
|
||||
}
|
@ -1,389 +0,0 @@
|
||||
// Copyright 2020 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/>.
|
||||
|
||||
package nodestate
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/mclock"
|
||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
"github.com/ethereum/go-ethereum/p2p/enr"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
)
|
||||
|
||||
func testSetup(flagPersist []bool, fieldType []reflect.Type) (*Setup, []Flags, []Field) {
|
||||
setup := &Setup{}
|
||||
flags := make([]Flags, len(flagPersist))
|
||||
for i, persist := range flagPersist {
|
||||
if persist {
|
||||
flags[i] = setup.NewPersistentFlag(fmt.Sprintf("flag-%d", i))
|
||||
} else {
|
||||
flags[i] = setup.NewFlag(fmt.Sprintf("flag-%d", i))
|
||||
}
|
||||
}
|
||||
fields := make([]Field, len(fieldType))
|
||||
for i, ftype := range fieldType {
|
||||
switch ftype {
|
||||
case reflect.TypeOf(uint64(0)):
|
||||
fields[i] = setup.NewPersistentField(fmt.Sprintf("field-%d", i), ftype, uint64FieldEnc, uint64FieldDec)
|
||||
case reflect.TypeOf(""):
|
||||
fields[i] = setup.NewPersistentField(fmt.Sprintf("field-%d", i), ftype, stringFieldEnc, stringFieldDec)
|
||||
default:
|
||||
fields[i] = setup.NewField(fmt.Sprintf("field-%d", i), ftype)
|
||||
}
|
||||
}
|
||||
return setup, flags, fields
|
||||
}
|
||||
|
||||
func testNode(b byte) *enode.Node {
|
||||
r := &enr.Record{}
|
||||
r.SetSig(dummyIdentity{b}, []byte{42})
|
||||
n, _ := enode.New(dummyIdentity{b}, r)
|
||||
return n
|
||||
}
|
||||
|
||||
func TestCallback(t *testing.T) {
|
||||
mdb, clock := rawdb.NewMemoryDatabase(), &mclock.Simulated{}
|
||||
|
||||
s, flags, _ := testSetup([]bool{false, false, false}, nil)
|
||||
ns := NewNodeStateMachine(mdb, []byte("-ns"), clock, s)
|
||||
|
||||
set0 := make(chan struct{}, 1)
|
||||
set1 := make(chan struct{}, 1)
|
||||
set2 := make(chan struct{}, 1)
|
||||
ns.SubscribeState(flags[0], func(n *enode.Node, oldState, newState Flags) { set0 <- struct{}{} })
|
||||
ns.SubscribeState(flags[1], func(n *enode.Node, oldState, newState Flags) { set1 <- struct{}{} })
|
||||
ns.SubscribeState(flags[2], func(n *enode.Node, oldState, newState Flags) { set2 <- struct{}{} })
|
||||
|
||||
ns.Start()
|
||||
|
||||
ns.SetState(testNode(1), flags[0], Flags{}, 0)
|
||||
ns.SetState(testNode(1), flags[1], Flags{}, time.Second)
|
||||
ns.SetState(testNode(1), flags[2], Flags{}, 2*time.Second)
|
||||
|
||||
for i := 0; i < 3; i++ {
|
||||
select {
|
||||
case <-set0:
|
||||
case <-set1:
|
||||
case <-set2:
|
||||
case <-time.After(time.Second):
|
||||
t.Fatalf("failed to invoke callback")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPersistentFlags(t *testing.T) {
|
||||
mdb, clock := rawdb.NewMemoryDatabase(), &mclock.Simulated{}
|
||||
|
||||
s, flags, _ := testSetup([]bool{true, true, true, false}, nil)
|
||||
ns := NewNodeStateMachine(mdb, []byte("-ns"), clock, s)
|
||||
|
||||
saveNode := make(chan *nodeInfo, 5)
|
||||
ns.saveNodeHook = func(node *nodeInfo) {
|
||||
saveNode <- node
|
||||
}
|
||||
|
||||
ns.Start()
|
||||
|
||||
ns.SetState(testNode(1), flags[0], Flags{}, time.Second) // state with timeout should not be saved
|
||||
ns.SetState(testNode(2), flags[1], Flags{}, 0)
|
||||
ns.SetState(testNode(3), flags[2], Flags{}, 0)
|
||||
ns.SetState(testNode(4), flags[3], Flags{}, 0)
|
||||
ns.SetState(testNode(5), flags[0], Flags{}, 0)
|
||||
ns.Persist(testNode(5))
|
||||
select {
|
||||
case <-saveNode:
|
||||
case <-time.After(time.Second):
|
||||
t.Fatalf("Timeout")
|
||||
}
|
||||
ns.Stop()
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
select {
|
||||
case <-saveNode:
|
||||
case <-time.After(time.Second):
|
||||
t.Fatalf("Timeout")
|
||||
}
|
||||
}
|
||||
select {
|
||||
case <-saveNode:
|
||||
t.Fatalf("Unexpected saveNode")
|
||||
case <-time.After(time.Millisecond * 100):
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetField(t *testing.T) {
|
||||
mdb, clock := rawdb.NewMemoryDatabase(), &mclock.Simulated{}
|
||||
|
||||
s, flags, fields := testSetup([]bool{true}, []reflect.Type{reflect.TypeOf("")})
|
||||
ns := NewNodeStateMachine(mdb, []byte("-ns"), clock, s)
|
||||
|
||||
saveNode := make(chan *nodeInfo, 1)
|
||||
ns.saveNodeHook = func(node *nodeInfo) {
|
||||
saveNode <- node
|
||||
}
|
||||
|
||||
ns.Start()
|
||||
|
||||
// Set field before setting state
|
||||
ns.SetField(testNode(1), fields[0], "hello world")
|
||||
field := ns.GetField(testNode(1), fields[0])
|
||||
if field != nil {
|
||||
t.Fatalf("Field shouldn't be set before setting states")
|
||||
}
|
||||
// Set field after setting state
|
||||
ns.SetState(testNode(1), flags[0], Flags{}, 0)
|
||||
ns.SetField(testNode(1), fields[0], "hello world")
|
||||
field = ns.GetField(testNode(1), fields[0])
|
||||
if field == nil {
|
||||
t.Fatalf("Field should be set after setting states")
|
||||
}
|
||||
if err := ns.SetField(testNode(1), fields[0], 123); err == nil {
|
||||
t.Fatalf("Invalid field should be rejected")
|
||||
}
|
||||
// Dirty node should be written back
|
||||
ns.Stop()
|
||||
select {
|
||||
case <-saveNode:
|
||||
case <-time.After(time.Second):
|
||||
t.Fatalf("Timeout")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnsetField(t *testing.T) {
|
||||
mdb, clock := rawdb.NewMemoryDatabase(), &mclock.Simulated{}
|
||||
|
||||
s, flags, fields := testSetup([]bool{false}, []reflect.Type{reflect.TypeOf("")})
|
||||
ns := NewNodeStateMachine(mdb, []byte("-ns"), clock, s)
|
||||
|
||||
ns.Start()
|
||||
|
||||
ns.SetState(testNode(1), flags[0], Flags{}, time.Second)
|
||||
ns.SetField(testNode(1), fields[0], "hello world")
|
||||
|
||||
ns.SetState(testNode(1), Flags{}, flags[0], 0)
|
||||
if field := ns.GetField(testNode(1), fields[0]); field != nil {
|
||||
t.Fatalf("Field should be unset")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetState(t *testing.T) {
|
||||
mdb, clock := rawdb.NewMemoryDatabase(), &mclock.Simulated{}
|
||||
|
||||
s, flags, _ := testSetup([]bool{false, false, false}, nil)
|
||||
ns := NewNodeStateMachine(mdb, []byte("-ns"), clock, s)
|
||||
|
||||
type change struct{ old, new Flags }
|
||||
set := make(chan change, 1)
|
||||
ns.SubscribeState(flags[0].Or(flags[1]), func(n *enode.Node, oldState, newState Flags) {
|
||||
set <- change{
|
||||
old: oldState,
|
||||
new: newState,
|
||||
}
|
||||
})
|
||||
|
||||
ns.Start()
|
||||
|
||||
check := func(expectOld, expectNew Flags, expectChange bool) {
|
||||
if expectChange {
|
||||
select {
|
||||
case c := <-set:
|
||||
if !c.old.Equals(expectOld) {
|
||||
t.Fatalf("Old state mismatch")
|
||||
}
|
||||
if !c.new.Equals(expectNew) {
|
||||
t.Fatalf("New state mismatch")
|
||||
}
|
||||
case <-time.After(time.Second):
|
||||
}
|
||||
return
|
||||
}
|
||||
select {
|
||||
case <-set:
|
||||
t.Fatalf("Unexpected change")
|
||||
case <-time.After(time.Millisecond * 100):
|
||||
return
|
||||
}
|
||||
}
|
||||
ns.SetState(testNode(1), flags[0], Flags{}, 0)
|
||||
check(Flags{}, flags[0], true)
|
||||
|
||||
ns.SetState(testNode(1), flags[1], Flags{}, 0)
|
||||
check(flags[0], flags[0].Or(flags[1]), true)
|
||||
|
||||
ns.SetState(testNode(1), flags[2], Flags{}, 0)
|
||||
check(Flags{}, Flags{}, false)
|
||||
|
||||
ns.SetState(testNode(1), Flags{}, flags[0], 0)
|
||||
check(flags[0].Or(flags[1]), flags[1], true)
|
||||
|
||||
ns.SetState(testNode(1), Flags{}, flags[1], 0)
|
||||
check(flags[1], Flags{}, true)
|
||||
|
||||
ns.SetState(testNode(1), Flags{}, flags[2], 0)
|
||||
check(Flags{}, Flags{}, false)
|
||||
|
||||
ns.SetState(testNode(1), flags[0].Or(flags[1]), Flags{}, time.Second)
|
||||
check(Flags{}, flags[0].Or(flags[1]), true)
|
||||
clock.Run(time.Second)
|
||||
check(flags[0].Or(flags[1]), Flags{}, true)
|
||||
}
|
||||
|
||||
func uint64FieldEnc(field interface{}) ([]byte, error) {
|
||||
if u, ok := field.(uint64); ok {
|
||||
enc, err := rlp.EncodeToBytes(&u)
|
||||
return enc, err
|
||||
} else {
|
||||
return nil, errors.New("invalid field type")
|
||||
}
|
||||
}
|
||||
|
||||
func uint64FieldDec(enc []byte) (interface{}, error) {
|
||||
var u uint64
|
||||
err := rlp.DecodeBytes(enc, &u)
|
||||
return u, err
|
||||
}
|
||||
|
||||
func stringFieldEnc(field interface{}) ([]byte, error) {
|
||||
if s, ok := field.(string); ok {
|
||||
return []byte(s), nil
|
||||
} else {
|
||||
return nil, errors.New("invalid field type")
|
||||
}
|
||||
}
|
||||
|
||||
func stringFieldDec(enc []byte) (interface{}, error) {
|
||||
return string(enc), nil
|
||||
}
|
||||
|
||||
func TestPersistentFields(t *testing.T) {
|
||||
mdb, clock := rawdb.NewMemoryDatabase(), &mclock.Simulated{}
|
||||
|
||||
s, flags, fields := testSetup([]bool{true}, []reflect.Type{reflect.TypeOf(uint64(0)), reflect.TypeOf("")})
|
||||
ns := NewNodeStateMachine(mdb, []byte("-ns"), clock, s)
|
||||
|
||||
ns.Start()
|
||||
ns.SetState(testNode(1), flags[0], Flags{}, 0)
|
||||
ns.SetField(testNode(1), fields[0], uint64(100))
|
||||
ns.SetField(testNode(1), fields[1], "hello world")
|
||||
ns.Stop()
|
||||
|
||||
ns2 := NewNodeStateMachine(mdb, []byte("-ns"), clock, s)
|
||||
|
||||
ns2.Start()
|
||||
field0 := ns2.GetField(testNode(1), fields[0])
|
||||
if !reflect.DeepEqual(field0, uint64(100)) {
|
||||
t.Fatalf("Field changed")
|
||||
}
|
||||
field1 := ns2.GetField(testNode(1), fields[1])
|
||||
if !reflect.DeepEqual(field1, "hello world") {
|
||||
t.Fatalf("Field changed")
|
||||
}
|
||||
|
||||
s.Version++
|
||||
ns3 := NewNodeStateMachine(mdb, []byte("-ns"), clock, s)
|
||||
ns3.Start()
|
||||
if ns3.GetField(testNode(1), fields[0]) != nil {
|
||||
t.Fatalf("Old field version should have been discarded")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFieldSub(t *testing.T) {
|
||||
mdb, clock := rawdb.NewMemoryDatabase(), &mclock.Simulated{}
|
||||
|
||||
s, flags, fields := testSetup([]bool{true}, []reflect.Type{reflect.TypeOf(uint64(0))})
|
||||
ns := NewNodeStateMachine(mdb, []byte("-ns"), clock, s)
|
||||
|
||||
var (
|
||||
lastState Flags
|
||||
lastOldValue, lastNewValue interface{}
|
||||
)
|
||||
ns.SubscribeField(fields[0], func(n *enode.Node, state Flags, oldValue, newValue interface{}) {
|
||||
lastState, lastOldValue, lastNewValue = state, oldValue, newValue
|
||||
})
|
||||
check := func(state Flags, oldValue, newValue interface{}) {
|
||||
if !lastState.Equals(state) || lastOldValue != oldValue || lastNewValue != newValue {
|
||||
t.Fatalf("Incorrect field sub callback (expected [%v %v %v], got [%v %v %v])", state, oldValue, newValue, lastState, lastOldValue, lastNewValue)
|
||||
}
|
||||
}
|
||||
ns.Start()
|
||||
ns.SetState(testNode(1), flags[0], Flags{}, 0)
|
||||
ns.SetField(testNode(1), fields[0], uint64(100))
|
||||
check(flags[0], nil, uint64(100))
|
||||
ns.Stop()
|
||||
check(s.OfflineFlag(), uint64(100), nil)
|
||||
|
||||
ns2 := NewNodeStateMachine(mdb, []byte("-ns"), clock, s)
|
||||
ns2.SubscribeField(fields[0], func(n *enode.Node, state Flags, oldValue, newValue interface{}) {
|
||||
lastState, lastOldValue, lastNewValue = state, oldValue, newValue
|
||||
})
|
||||
ns2.Start()
|
||||
check(s.OfflineFlag(), nil, uint64(100))
|
||||
ns2.SetState(testNode(1), Flags{}, flags[0], 0)
|
||||
check(Flags{}, uint64(100), nil)
|
||||
ns2.Stop()
|
||||
}
|
||||
|
||||
func TestDuplicatedFlags(t *testing.T) {
|
||||
mdb, clock := rawdb.NewMemoryDatabase(), &mclock.Simulated{}
|
||||
|
||||
s, flags, _ := testSetup([]bool{true}, nil)
|
||||
ns := NewNodeStateMachine(mdb, []byte("-ns"), clock, s)
|
||||
|
||||
type change struct{ old, new Flags }
|
||||
set := make(chan change, 1)
|
||||
ns.SubscribeState(flags[0], func(n *enode.Node, oldState, newState Flags) {
|
||||
set <- change{oldState, newState}
|
||||
})
|
||||
|
||||
ns.Start()
|
||||
defer ns.Stop()
|
||||
|
||||
check := func(expectOld, expectNew Flags, expectChange bool) {
|
||||
if expectChange {
|
||||
select {
|
||||
case c := <-set:
|
||||
if !c.old.Equals(expectOld) {
|
||||
t.Fatalf("Old state mismatch")
|
||||
}
|
||||
if !c.new.Equals(expectNew) {
|
||||
t.Fatalf("New state mismatch")
|
||||
}
|
||||
case <-time.After(time.Second):
|
||||
}
|
||||
return
|
||||
}
|
||||
select {
|
||||
case <-set:
|
||||
t.Fatalf("Unexpected change")
|
||||
case <-time.After(time.Millisecond * 100):
|
||||
return
|
||||
}
|
||||
}
|
||||
ns.SetState(testNode(1), flags[0], Flags{}, time.Second)
|
||||
check(Flags{}, flags[0], true)
|
||||
ns.SetState(testNode(1), flags[0], Flags{}, 2*time.Second) // extend the timeout to 2s
|
||||
check(Flags{}, flags[0], false)
|
||||
|
||||
clock.Run(2 * time.Second)
|
||||
check(flags[0], Flags{}, true)
|
||||
}
|
@ -490,7 +490,7 @@ func (c *ChainConfig) CheckConfigForkOrder() error {
|
||||
lastFork.name, lastFork.block, cur.name, cur.block)
|
||||
}
|
||||
}
|
||||
// If it was optional and not set, then ignore it
|
||||
// If it was optional and not set, then ignore it
|
||||
}
|
||||
if !cur.optional || cur.block != nil {
|
||||
lastFork = cur
|
||||
@ -535,8 +535,8 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *Confi
|
||||
}
|
||||
if isForkIncompatible(c.MuirGlacierBlock, newcfg.MuirGlacierBlock, head) {
|
||||
return newCompatError("Muir Glacier fork block", c.MuirGlacierBlock, newcfg.MuirGlacierBlock)
|
||||
if isForkIncompatible(c.YoloV1Block, newcfg.YoloV1Block, head) {
|
||||
}
|
||||
if isForkIncompatible(c.YoloV1Block, newcfg.YoloV1Block, head) {
|
||||
return newCompatError("YOLOv1 fork block", c.YoloV1Block, newcfg.YoloV1Block)
|
||||
}
|
||||
if isForkIncompatible(c.EWASMBlock, newcfg.EWASMBlock, head) {
|
||||
|
@ -225,8 +225,8 @@ func (wc *websocketCodec) pingLoop() {
|
||||
timer.Reset(wsPingInterval)
|
||||
case <-timer.C:
|
||||
wc.jsonCodec.encMu.Lock()
|
||||
wc.conn.SetWriteDeadline(time.Now().Add(wsPingWriteTimeout))
|
||||
wc.conn.WriteMessage(websocket.PingMessage, nil)
|
||||
wc.conn.SetWriteDeadline(time.Now().Add(wsPingWriteTimeout)) //nolint:errcheck
|
||||
wc.conn.WriteMessage(websocket.PingMessage, nil) //nolint:errcheck
|
||||
wc.jsonCodec.encMu.Unlock()
|
||||
timer.Reset(wsPingInterval)
|
||||
}
|
||||
|
@ -28,7 +28,6 @@ import (
|
||||
"github.com/ledgerwatch/turbo-geth/console/prompt"
|
||||
"github.com/ledgerwatch/turbo-geth/internal/ethapi"
|
||||
"github.com/ledgerwatch/turbo-geth/log"
|
||||
"golang.org/x/crypto/ssh/terminal"
|
||||
)
|
||||
|
||||
type CommandlineUI struct {
|
||||
|
376
to-merge.txt
376
to-merge.txt
@ -1,376 +0,0 @@
|
||||
commit 0f77f34bb67b640bd8af22b215f3d279a1e21170
|
||||
Author: Felix Lange <fjl@twurst.com>
|
||||
Date: Mon Jun 8 10:56:48 2020 +0200
|
||||
|
||||
params: go-ethereum v1.9.15 stable
|
||||
|
||||
commit 651233454ee0e7e091162fe1631072ae05016e0a
|
||||
Merge: 0b3f3be2b a5c827af8
|
||||
Author: Péter Szilágyi <peterke@gmail.com>
|
||||
Date: Mon Jun 8 11:16:23 2020 +0300
|
||||
|
||||
Merge pull request #21188 from karalabe/cht-1.9.15
|
||||
|
||||
params: update CHTs for 1.9.15 release
|
||||
|
||||
commit a5c827af86a81a3e2d0a1ea09582fde2bf96a7dd
|
||||
Author: Péter Szilágyi <peterke@gmail.com>
|
||||
Date: Mon Jun 8 11:14:33 2020 +0300
|
||||
|
||||
params: update CHTs for 1.9.15 release
|
||||
|
||||
commit 0b3f3be2b5dde72c6292bfb16915ad763d4aa0bd
|
||||
Author: Marius van der Wijden <m.vanderwijden@live.de>
|
||||
Date: Mon Jun 8 10:09:49 2020 +0200
|
||||
|
||||
internal/ethapi: return revert reason for eth_call (#21083)
|
||||
|
||||
* internal/ethapi: return revert reason for eth_call
|
||||
|
||||
* internal/ethapi: moved revert reason logic to doCall
|
||||
|
||||
* accounts/abi/bind/backends: added revert reason logic to simulated backend
|
||||
|
||||
* internal/ethapi: fixed linting error
|
||||
|
||||
* internal/ethapi: check if require reason can be unpacked
|
||||
|
||||
* internal/ethapi: better error logic
|
||||
|
||||
* internal/ethapi: simplify logic
|
||||
|
||||
* internal/ethapi: return vmError()
|
||||
|
||||
* internal/ethapi: move handling of revert out of docall
|
||||
|
||||
* graphql: removed revert logic until spec change
|
||||
|
||||
* rpc: internal/ethapi: added custom error types
|
||||
|
||||
* graphql: use returndata instead of return
|
||||
|
||||
Return() checks if there is an error. If an error is found, we return nil.
|
||||
For most use cases it can be beneficial to return the output even if there
|
||||
was an error. This code should be changed anyway once the spec supports
|
||||
error reasons in graphql responses
|
||||
|
||||
* accounts/abi/bind/backends: added tests for revert reason
|
||||
|
||||
* internal/ethapi: add errorCode to revert error
|
||||
|
||||
* internal/ethapi: add errorCode of 3 to revertError
|
||||
|
||||
* internal/ethapi: unified estimateGasErrors, simplified logic
|
||||
|
||||
* internal/ethapi: unified handling of errors in DoEstimateGas
|
||||
|
||||
* rpc: print error data field
|
||||
|
||||
* accounts/abi/bind/backends: unify simulatedBackend and RPC
|
||||
|
||||
* internal/ethapi: added binary data to revertError data
|
||||
|
||||
* internal/ethapi: refactored unpacking logic into newRevertError
|
||||
|
||||
* accounts/abi/bind/backends: fix EstimateGas
|
||||
|
||||
* accounts, console, internal, rpc: minor error interface cleanups
|
||||
|
||||
* Revert "accounts, console, internal, rpc: minor error interface cleanups"
|
||||
|
||||
This reverts commit 2d3ef53c5304e429a04983210a417c1f4e0dafb7.
|
||||
|
||||
* re-apply the good parts of 2d3ef53c53
|
||||
|
||||
* rpc: add test for returning server error data from client
|
||||
|
||||
Co-authored-by: rjl493456442 <garyrong0905@gmail.com>
|
||||
Co-authored-by: Péter Szilágyi <peterke@gmail.com>
|
||||
Co-authored-by: Felix Lange <fjl@twurst.com>
|
||||
|
||||
commit 88125d8bd00759bdce319b5cb0e8db0d9223962f
|
||||
Author: Ev <ev@ethereum.org>
|
||||
Date: Mon Jun 8 03:53:56 2020 -0400
|
||||
|
||||
core: fix typo in comments (#21181)
|
||||
|
||||
commit 55f30db0aef3a44a6d3f93e6f21a7722bd7cba86
|
||||
Author: Marius van der Wijden <m.vanderwijden@live.de>
|
||||
Date: Mon Jun 8 09:53:19 2020 +0200
|
||||
|
||||
core/vm, crypt/bls12381: fixed comments in bls (#21182)
|
||||
|
||||
* core/vm: crypto/bls12381: minor code comments
|
||||
|
||||
* crypto/bls12381: fix comment
|
||||
|
||||
commit 9d9353567486d1537afb3ecad33a2527aee53c54
|
||||
Author: Mariano Cortesi <mcortesi@gmail.com>
|
||||
Date: Mon Jun 8 04:52:18 2020 -0300
|
||||
|
||||
node: missing comma on toml tags (#21187)
|
||||
|
||||
commit 4b2ff1457ac28fb2894485194e0e344e84c2bcd7
|
||||
Author: ucwong <ucwong@126.com>
|
||||
Date: Thu Jun 4 23:42:05 2020 +0800
|
||||
|
||||
go.mod: upgrade go-duktape to hide unused function warning (#21168)
|
||||
|
||||
commit cefa2ab1bd18f7793df736cb643fed50d29494f4
|
||||
Merge: 201e345c6 b1b75f008
|
||||
Author: Péter Szilágyi <peterke@gmail.com>
|
||||
Date: Thu Jun 4 11:58:40 2020 +0300
|
||||
|
||||
Merge pull request #21173 from karalabe/faucet-delete-oldaccs
|
||||
|
||||
cmd/faucet: delete old keystore when importing new faucet key
|
||||
|
||||
commit b1b75f00893ed9e290e8466c86e601ab1fe63bc7
|
||||
Author: Péter Szilágyi <peterke@gmail.com>
|
||||
Date: Thu Jun 4 10:22:11 2020 +0300
|
||||
|
||||
accounts/keystore, cmd/faucet: return old account to allow unlock
|
||||
|
||||
commit 201e345c65c9940edf03c9d2b43133e35b40e613
|
||||
Merge: 8b8312573 469b8739e
|
||||
Author: Péter Szilágyi <peterke@gmail.com>
|
||||
Date: Thu Jun 4 09:30:40 2020 +0300
|
||||
|
||||
Merge pull request #21172 from karalabe/faucet-twitter-mobile
|
||||
|
||||
acounts/keystore, cmd/faucet: fix faucet double import, fix twitter url
|
||||
|
||||
commit 469b8739ebbe45997d8e287bcd441544ebfebfda
|
||||
Author: Péter Szilágyi <peterke@gmail.com>
|
||||
Date: Thu Jun 4 08:59:26 2020 +0300
|
||||
|
||||
acounts/keystore, cmd/faucet: fix faucet double import, fix twitter url
|
||||
|
||||
commit 8b83125739c28caf97b3c2c36b084cedb3fe682e
|
||||
Merge: 890757f03 f52ff0f1e
|
||||
Author: Péter Szilágyi <peterke@gmail.com>
|
||||
Date: Wed Jun 3 12:20:57 2020 +0300
|
||||
|
||||
Merge pull request #21162 from karalabe/daofork-order-check-fix
|
||||
|
||||
cmd/geth: fix the fork orders for DAO tests
|
||||
|
||||
commit f52ff0f1e99ee2adbe4bd8f5ffdbce8e19a0b5dd
|
||||
Author: Péter Szilágyi <peterke@gmail.com>
|
||||
Date: Wed Jun 3 12:17:54 2020 +0300
|
||||
|
||||
cmd/geth: fix the fork orders for DAO tests
|
||||
|
||||
commit 890757f03acf9974cfac07d27197803d455d67c9
|
||||
Author: Martin Holst Swende <martin@swende.se>
|
||||
Date: Wed Jun 3 11:05:15 2020 +0200
|
||||
|
||||
cmd, core, params: inital support for yolo-v1 testnet (#21154)
|
||||
|
||||
* core,params,puppeth: inital support for yolo-v1 testnet
|
||||
|
||||
* cmd/geth, core: add yolov1 console flag
|
||||
|
||||
* cmd, core, params: YoloV1 bakein fixups
|
||||
|
||||
Co-authored-by: Péter Szilágyi <peterke@gmail.com>
|
||||
|
||||
commit 4fc678542dd287c9759107d7f1f2291376434f5e
|
||||
Author: kilic <onurkilic1004@gmail.com>
|
||||
Date: Wed Jun 3 09:44:32 2020 +0300
|
||||
|
||||
core/vm, crypto/bls12381, params: add bls12-381 elliptic curve precompiles (#21018)
|
||||
|
||||
* crypto: add bls12-381 elliptic curve wrapper
|
||||
|
||||
* params: add bls12-381 precompile gas parameters
|
||||
|
||||
* core/vm: add bls12-381 precompiles
|
||||
|
||||
* core/vm: add bls12-381 precompile tests
|
||||
|
||||
* go.mod, go.sum: use latest bls12381 lib
|
||||
|
||||
* core/vm: move point encode/decode functions to base library
|
||||
|
||||
* crypto/bls12381: introduce bls12-381 library init function
|
||||
|
||||
* crypto/bls12381: import bls12381 elliptic curve implementation
|
||||
|
||||
* go.mod, go.sum: remove bls12-381 library
|
||||
|
||||
* remove unsued frobenious coeffs
|
||||
|
||||
supress warning for inp that used in asm
|
||||
|
||||
* add mappings tests for zero inputs
|
||||
|
||||
fix swu g2 minus z inverse constant
|
||||
|
||||
* crypto/bls12381: fix typo
|
||||
|
||||
* crypto/bls12381: better comments for bls12381 constants
|
||||
|
||||
* crypto/bls12381: swu, use single conditional for e2
|
||||
|
||||
* crypto/bls12381: utils, delete empty line
|
||||
|
||||
* crypto/bls12381: utils, use FromHex for string to big
|
||||
|
||||
* crypto/bls12381: g1, g2, strict length check for FromBytes
|
||||
|
||||
* crypto/bls12381: field_element, comparision changes
|
||||
|
||||
* crypto/bls12381: change swu, isogeny constants with hex values
|
||||
|
||||
* core/vm: fix point multiplication comments
|
||||
|
||||
* core/vm: fix multiexp gas calculation and lookup for g1 and g2
|
||||
|
||||
* core/vm: simpler imput length check for multiexp and pairing precompiles
|
||||
|
||||
* core/vm: rm empty multiexp result declarations
|
||||
|
||||
* crypto/bls12381: remove modulus type definition
|
||||
|
||||
* crypto/bls12381: use proper init function
|
||||
|
||||
* crypto/bls12381: get rid of new lines at fatal desciprtions
|
||||
|
||||
* crypto/bls12-381: fix no-adx assembly multiplication
|
||||
|
||||
* crypto/bls12-381: remove old config function
|
||||
|
||||
* crypto/bls12381: update multiplication backend
|
||||
|
||||
this commit changes mul backend to 6limb eip1962 backend
|
||||
|
||||
mul assign operations are dropped
|
||||
|
||||
* core/vm/contracts_tests: externalize test vectors for precompiles
|
||||
|
||||
* core/vm/contracts_test: externalize failure-cases for precompiles
|
||||
|
||||
* core/vm: linting
|
||||
|
||||
* go.mod: tiny up sum file
|
||||
|
||||
* core/vm: fix goimports linter issues
|
||||
|
||||
* crypto/bls12381: build tags for plain ASM or ADX implementation
|
||||
|
||||
Co-authored-by: Martin Holst Swende <martin@swende.se>
|
||||
Co-authored-by: Péter Szilágyi <peterke@gmail.com>
|
||||
|
||||
commit 3f649d4852d5e7a16f47d919bf0e450c450bc6bf
|
||||
Author: chenglin <910372762@qq.com>
|
||||
Date: Wed Jun 3 00:52:20 2020 +0800
|
||||
|
||||
core: collect NewTxsEvent items without holding reorg lock (#21145)
|
||||
|
||||
commit 5f6f5e345ea3fd19d031cb2ae3c8d2894e51639e
|
||||
Author: Guillaume Ballet <gballet@gmail.com>
|
||||
Date: Tue Jun 2 18:06:22 2020 +0200
|
||||
|
||||
console: handle undefined + null in console funcs (#21160)
|
||||
|
||||
commit d98c42c0e37da20df8af74724fbd032b342035ab
|
||||
Author: Felix Lange <fjl@twurst.com>
|
||||
Date: Tue Jun 2 14:04:44 2020 +0200
|
||||
|
||||
rpc: send websocket ping when connection is idle (#21142)
|
||||
|
||||
* rpc: send websocket ping when connection is idle
|
||||
|
||||
* rpc: use non-blocking send for websocket pingReset
|
||||
|
||||
commit 723bd8c17fdf1614d81503efdca9e7eece3766a6
|
||||
Author: Felix Lange <fjl@twurst.com>
|
||||
Date: Tue Jun 2 13:20:19 2020 +0200
|
||||
|
||||
p2p/discover: move discv4 encoding to new 'v4wire' package (#21147)
|
||||
|
||||
This moves all v4 protocol definitions to a new package, p2p/discover/v4wire.
|
||||
The new package will be used for low-level protocol tests.
|
||||
|
||||
commit cd57d5cd38ef692de8fbedaa56598b4e9fbfbabc
|
||||
Author: Greg Colvin <greg@colvin.org>
|
||||
Date: Tue Jun 2 04:30:16 2020 -0600
|
||||
|
||||
core/vm: EIP-2315, JUMPSUB for the EVM (#20619)
|
||||
|
||||
* core/vm: implement EIP 2315, subroutines for the EVM
|
||||
|
||||
* core/vm: eip 2315 - lintfix + check jump dest validity + check ret stack size constraints
|
||||
|
||||
logger: markdown-friendly traces, validate jumpdest, more testcase, correct opcodes
|
||||
|
||||
* core/vm: update subroutines acc to eip: disallow walk-into
|
||||
|
||||
* core/vm/eips: gas cost changes for subroutines
|
||||
|
||||
* core/vm: update opcodes for EIP-2315
|
||||
|
||||
* core/vm: define RETURNSUB as a 'jumping' operation + review concerns
|
||||
|
||||
Co-authored-by: Martin Holst Swende <martin@swende.se>
|
||||
|
||||
commit a35382de94fe3d0b7ef8a1719ba3e20a1b5af84c
|
||||
Author: rene <41963722+renaynay@users.noreply.github.com>
|
||||
Date: Tue Jun 2 11:08:33 2020 +0200
|
||||
|
||||
metrics: replace gosigar with gopsutil (#21041)
|
||||
|
||||
* replace gosigar with gopsutil
|
||||
|
||||
* removed check for whether GOOS is openbsd
|
||||
|
||||
* removed accidental import of runtime
|
||||
|
||||
* potential fix for difference in units between gosig and gopsutil
|
||||
|
||||
* fixed lint error
|
||||
|
||||
* remove multiplication factor
|
||||
|
||||
* uses cpu.ClocksPerSec as the multiplication factor
|
||||
|
||||
* changed dependency from shirou to renaynay (#20)
|
||||
|
||||
* updated dep
|
||||
|
||||
* switching back from using renaynay fork to using upstream as PRs were merged on upstream
|
||||
|
||||
* removed empty line
|
||||
|
||||
* optimized imports
|
||||
|
||||
* tidied go mod
|
||||
|
||||
commit a5eee8d1dc61352c29b9800eaf96609ba4184fd6
|
||||
Author: Martin Holst Swende <martin@swende.se>
|
||||
Date: Fri May 29 11:12:43 2020 +0200
|
||||
|
||||
eth/downloader: more context in errors (#21067)
|
||||
|
||||
This PR makes use of go 1.13 error handling, wrapping errors and using
|
||||
errors.Is to check a wrapped root-cause. It also removes the travis
|
||||
builders for go 1.11 and go 1.12.
|
||||
|
||||
commit 389da6aa480bdf9a78d865caabc39ebeebb1d416
|
||||
Author: Gary Rong <garyrong0905@gmail.com>
|
||||
Date: Wed May 27 22:37:37 2020 +0800
|
||||
|
||||
trie: enforce monotonic range in prover and return end marker (#21130)
|
||||
|
||||
* trie: add hasRightElement indicator
|
||||
|
||||
* trie: ensure the range is monotonic increasing
|
||||
|
||||
* trie: address comment and fix lint
|
||||
|
||||
* trie: address comment
|
||||
|
||||
* trie: make linter happy
|
||||
|
||||
Co-authored-by: Péter Szilágyi <peterke@gmail.com>
|
Loading…
Reference in New Issue
Block a user