DERO-HE STARGATE Testnet Release29
This commit is contained in:
parent
49651db052
commit
4501db42a4
@ -18,6 +18,8 @@ package block
|
||||
|
||||
import "fmt"
|
||||
import "time"
|
||||
import "hash"
|
||||
import "sync"
|
||||
import "strings"
|
||||
import "encoding/binary"
|
||||
|
||||
@ -28,6 +30,10 @@ import "github.com/deroproject/derohe/pow"
|
||||
|
||||
const MINIBLOCK_SIZE = 68
|
||||
|
||||
var hasherPool = sync.Pool{
|
||||
New: func() interface{} { return sha3.New256() },
|
||||
}
|
||||
|
||||
// it should be exactly 68 bytes after serialization
|
||||
// structure size 1 + 6 + 4 + 4 + 16 +32 + 5 bytes
|
||||
type MiniBlock struct {
|
||||
@ -91,9 +97,17 @@ func (mbl *MiniBlock) GetMiniID() uint32 {
|
||||
}
|
||||
|
||||
// this function gets the block identifier hash, this is only used to deduplicate mini blocks
|
||||
func (mbl *MiniBlock) GetHash() (hash crypto.Hash) {
|
||||
func (mbl *MiniBlock) GetHash() (result crypto.Hash) {
|
||||
ser := mbl.Serialize()
|
||||
return sha3.Sum256(ser[:])
|
||||
sha := hasherPool.Get().(hash.Hash)
|
||||
sha.Reset()
|
||||
sha.Write(ser[:])
|
||||
x := sha.Sum(nil)
|
||||
copy(result[:], x[:])
|
||||
hasherPool.Put(sha)
|
||||
return result
|
||||
|
||||
// return sha3.Sum256(ser[:])
|
||||
}
|
||||
|
||||
// Get PoW hash , this is very slow function
|
||||
|
@ -192,7 +192,7 @@ func (c *MiniBlocksCollection) GetAllTips() (mbls []MiniBlock) {
|
||||
|
||||
clone := map[uint32]MiniBlock{}
|
||||
|
||||
var clone_list []MiniBlock
|
||||
clone_list := make([]MiniBlock, 0, 64)
|
||||
for k, v := range c.Collection {
|
||||
clone[k] = v
|
||||
clone_list = append(clone_list, v)
|
||||
@ -273,6 +273,8 @@ func (c *MiniBlocksCollection) GetGenesisFromMiniBlock(mbl MiniBlock) (genesis [
|
||||
|
||||
// this works in all cases, but it may return truncated history,all returns must be checked for connectivity
|
||||
func (c *MiniBlocksCollection) GetEntireMiniBlockHistory(mbl MiniBlock) (history []MiniBlock) {
|
||||
|
||||
history = make([]MiniBlock, 0, 128)
|
||||
if mbl.Genesis {
|
||||
history = append(history, mbl)
|
||||
return
|
||||
@ -301,6 +303,7 @@ func (c *MiniBlocksCollection) GetEntireMiniBlockHistory(mbl MiniBlock) (history
|
||||
// gets the genesis from the tips
|
||||
// this function only works, if the miniblock has been expanded
|
||||
func GetGenesisFromMiniBlock(mbl MiniBlock) (genesis []MiniBlock) {
|
||||
|
||||
if mbl.Genesis {
|
||||
genesis = append(genesis, mbl)
|
||||
return
|
||||
@ -325,20 +328,36 @@ func GetGenesisFromMiniBlock(mbl MiniBlock) (genesis []MiniBlock) {
|
||||
|
||||
// get entire history,its in sorted form
|
||||
func GetEntireMiniBlockHistory(mbls ...MiniBlock) (history []MiniBlock) {
|
||||
var queue []MiniBlock
|
||||
queue := make([]MiniBlock, 0, 128)
|
||||
queue = append(queue, mbls...)
|
||||
history = make([]MiniBlock, 0, 128)
|
||||
unique := make([]MiniBlock, 0, 128)
|
||||
|
||||
unique_map := map[crypto.Hash]MiniBlock{}
|
||||
|
||||
for len(queue) > 0 {
|
||||
item := queue[0]
|
||||
queue = queue[1:] // Dequeue
|
||||
|
||||
if _, ok := unique_map[item.GetHash()]; !ok {
|
||||
unique_map[item.GetHash()] = item
|
||||
history = append(history, item) //mini blocks might be duplicated
|
||||
if !item.Genesis {
|
||||
queue = append(queue, item.PastMiniBlocks...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, v := range unique_map {
|
||||
unique = append(unique, v)
|
||||
}
|
||||
|
||||
history = MiniBlocks_Unique(history)
|
||||
|
||||
if len(unique) != len(history) {
|
||||
panic("result mismatch")
|
||||
}
|
||||
|
||||
history = MiniBlocks_SortByTimeAsc(history) // sort on the basis of timestamps
|
||||
|
||||
return
|
||||
@ -347,6 +366,7 @@ func GetEntireMiniBlockHistory(mbls ...MiniBlock) (history []MiniBlock) {
|
||||
// this sorts by distance, in descending order
|
||||
// if distance is equal, then it sorts by its id which is collision free
|
||||
func MiniBlocks_SortByDistanceDesc(mbls []MiniBlock) (sorted []MiniBlock) {
|
||||
sorted = make([]MiniBlock, 0, len(mbls))
|
||||
sorted = append(sorted, mbls...)
|
||||
sort.SliceStable(sorted, func(i, j int) bool { // sort descending on the basis of Distance
|
||||
if sorted[i].Distance == sorted[j].Distance {
|
||||
@ -360,6 +380,7 @@ func MiniBlocks_SortByDistanceDesc(mbls []MiniBlock) (sorted []MiniBlock) {
|
||||
// this sorts by timestamp,ascending order
|
||||
// if timestamp is equal, then it sorts by its id which is collision free
|
||||
func MiniBlocks_SortByTimeAsc(mbls []MiniBlock) (sorted []MiniBlock) {
|
||||
sorted = make([]MiniBlock, 0, len(mbls))
|
||||
sorted = append(sorted, mbls...)
|
||||
sort.SliceStable(sorted, func(i, j int) bool { // sort on the basis of timestamps
|
||||
if sorted[i].Timestamp == sorted[j].Timestamp {
|
||||
@ -371,6 +392,7 @@ func MiniBlocks_SortByTimeAsc(mbls []MiniBlock) (sorted []MiniBlock) {
|
||||
}
|
||||
|
||||
func MiniBlocks_Unique(mbls []MiniBlock) (unique []MiniBlock) {
|
||||
unique = make([]MiniBlock, 0, len(mbls))
|
||||
unique_map := map[crypto.Hash]MiniBlock{}
|
||||
for _, mbl := range mbls {
|
||||
unique_map[mbl.GetHash()] = mbl
|
||||
|
@ -71,6 +71,7 @@ type Blockchain struct {
|
||||
cache_Get_Difficulty_At_Tips *lru.Cache // used to cache some outputs
|
||||
cache_BlockPast *lru.Cache // used to cache a blocks past
|
||||
cache_BlockHeight *lru.Cache // used to cache a blocks past
|
||||
cache_VersionMerkle *lru.Cache // used to cache a versions merkle root
|
||||
|
||||
integrator_address rpc.Address // integrator rewards will be given to this address
|
||||
|
||||
@ -153,11 +154,15 @@ func Blockchain_Start(params map[string]interface{}) (*Blockchain, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if chain.cache_BlockPast, err = lru.New(100 * 1024); err != nil { // temporary cache for a blocks past
|
||||
if chain.cache_BlockPast, err = lru.New(1024); err != nil { // temporary cache for a blocks past
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if chain.cache_BlockHeight, err = lru.New(100 * 1024); err != nil { // temporary cache for a blocks height
|
||||
if chain.cache_BlockHeight, err = lru.New(10 * 1024); err != nil { // temporary cache for a blocks height
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if chain.cache_VersionMerkle, err = lru.New(1024); err != nil { // temporary cache for a snapshot version
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -231,11 +236,11 @@ func Blockchain_Start(params map[string]interface{}) (*Blockchain, error) {
|
||||
|
||||
top_block_topo_index := chain.Load_TOPO_HEIGHT()
|
||||
|
||||
if top_block_topo_index < 10 {
|
||||
if top_block_topo_index < 4 {
|
||||
return
|
||||
}
|
||||
|
||||
top_block_topo_index -= 10
|
||||
top_block_topo_index -= 4
|
||||
|
||||
blid, err := chain.Load_Block_Topological_order_at_index(top_block_topo_index)
|
||||
if err != nil {
|
||||
@ -689,7 +694,7 @@ func (chain *Blockchain) Add_Complete_Block(cbl *block.Complete_Block) (err erro
|
||||
if tx.SCDATA.Has(rpc.SCACTION, rpc.DataUint64) {
|
||||
if rpc.SC_INSTALL == rpc.SC_ACTION(tx.SCDATA.Value(rpc.SCACTION, rpc.DataUint64).(uint64)) {
|
||||
txid := tx.GetHash()
|
||||
if txid[31] < 0x80 { // last byte should be more than 0x80
|
||||
if txid[0] < 0x80 || txid[31] < 0x80 { // last byte should be more than 0x80
|
||||
block_logger.Error(fmt.Errorf("Invalid SCID"), "SCID installing tx must end with >0x80 byte", "txid", cbl.Txs[i].GetHash())
|
||||
return errormsg.ErrTXDoubleSpend, false
|
||||
}
|
||||
@ -1188,6 +1193,17 @@ func (chain *Blockchain) Add_TX_To_Pool(tx *transaction.Transaction) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if tx.TransactionType == transaction.SC_TX {
|
||||
if tx.SCDATA.Has(rpc.SCACTION, rpc.DataUint64) {
|
||||
if rpc.SC_INSTALL == rpc.SC_ACTION(tx.SCDATA.Value(rpc.SCACTION, rpc.DataUint64).(uint64)) {
|
||||
txid := tx.GetHash()
|
||||
if txid[0] < 0x80 || txid[31] < 0x80 { // last byte should be more than 0x80
|
||||
return fmt.Errorf("Invalid SCID ID,it must not start with 0x80")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := chain.Verify_Transaction_NonCoinbase_CheckNonce_Tips(hf_version, tx, chain.Get_TIPS()); err != nil { // transaction verification failed
|
||||
logger.V(1).Error(err, "Incoming TX nonce verification failed", "txid", txhash, "stacktrace", globals.StackTrace(false))
|
||||
return fmt.Errorf("Incoming TX %s nonce verification failed, err %s", txhash, err)
|
||||
|
@ -18,7 +18,6 @@ package blockchain
|
||||
|
||||
import "fmt"
|
||||
import "math/big"
|
||||
import "crypto/rand"
|
||||
import "path/filepath"
|
||||
|
||||
import "github.com/deroproject/derohe/globals"
|
||||
@ -55,9 +54,7 @@ func (s *storage) Initialize(params map[string]interface{}) (err error) {
|
||||
}
|
||||
|
||||
func (s *storage) IsBalancesIntialized() bool {
|
||||
|
||||
var err error
|
||||
var buf [64]byte
|
||||
var balancehash, random_hash [32]byte
|
||||
|
||||
balance_ss, _ := s.Balance_store.LoadSnapshot(0) // load most recent snapshot
|
||||
@ -65,15 +62,13 @@ func (s *storage) IsBalancesIntialized() bool {
|
||||
|
||||
// avoid hardcoding any hash
|
||||
if balancehash, err = balancetree.Hash(); err == nil {
|
||||
if _, err = rand.Read(buf[:]); err == nil {
|
||||
random_tree, _ := balance_ss.GetTree(string(buf[:]))
|
||||
random_tree, _ := balance_ss.GetTree(config.SC_META)
|
||||
if random_hash, err = random_tree.Hash(); err == nil {
|
||||
if random_hash == balancehash {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
panic("database issues")
|
||||
@ -300,6 +295,11 @@ func (chain *Blockchain) Load_Block_Topological_order_at_index(index_pos int64)
|
||||
//load store hash from 2 tree
|
||||
func (chain *Blockchain) Load_Merkle_Hash(version uint64) (hash crypto.Hash, err error) {
|
||||
|
||||
if hashi, ok := chain.cache_VersionMerkle.Get(version); ok {
|
||||
hash = hashi.(crypto.Hash)
|
||||
return
|
||||
}
|
||||
|
||||
ss, err := chain.Store.Balance_store.LoadSnapshot(version)
|
||||
if err != nil {
|
||||
return
|
||||
@ -324,5 +324,9 @@ func (chain *Blockchain) Load_Merkle_Hash(version uint64) (hash crypto.Hash, err
|
||||
for i := range balance_merkle_hash {
|
||||
hash[i] = balance_merkle_hash[i] ^ meta_merkle_hash[i]
|
||||
}
|
||||
|
||||
if chain.cache_enabled { //set in cache
|
||||
chain.cache_VersionMerkle.Add(version, hash)
|
||||
}
|
||||
return hash, nil
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ func clean_up_valid_cache() {
|
||||
current_time := time.Now()
|
||||
transaction_valid_cache.Range(func(k, value interface{}) bool {
|
||||
first_seen := value.(time.Time)
|
||||
if current_time.Sub(first_seen).Round(time.Second).Seconds() > 3600 {
|
||||
if current_time.Sub(first_seen).Round(time.Second).Seconds() > 360 {
|
||||
transaction_valid_cache.Delete(k)
|
||||
}
|
||||
return true
|
||||
|
@ -26,6 +26,7 @@ import "bufio"
|
||||
import "strings"
|
||||
import "strconv"
|
||||
import "runtime"
|
||||
import "runtime/debug"
|
||||
import "math/big"
|
||||
import "os/signal"
|
||||
import "io/ioutil"
|
||||
@ -89,9 +90,24 @@ var Exit_In_Progress = make(chan bool)
|
||||
|
||||
var logger logr.Logger
|
||||
|
||||
func dump(filename string) {
|
||||
f, err := os.Create(filename)
|
||||
if err != nil {
|
||||
fmt.Printf("err creating file %s\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
runtime.GC()
|
||||
debug.WriteHeapDump(f.Fd())
|
||||
|
||||
err = f.Close()
|
||||
if err != nil {
|
||||
fmt.Printf("err closing file %s\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
var err error
|
||||
|
||||
globals.Arguments, err = docopt.Parse(command_line, nil, true, config.Version.String(), false)
|
||||
|
||||
if err != nil {
|
||||
@ -781,6 +797,12 @@ restart_loop:
|
||||
|
||||
case command == "gc":
|
||||
runtime.GC()
|
||||
case command == "heap":
|
||||
if len(line_parts) == 1 {
|
||||
fmt.Printf("heap needs a filename to write\n")
|
||||
break
|
||||
}
|
||||
dump(line_parts[1])
|
||||
|
||||
case command == "ban":
|
||||
|
||||
|
@ -103,7 +103,7 @@ var Mainnet = CHAIN_CONFIG{Name: "mainnet",
|
||||
}
|
||||
|
||||
var Testnet = CHAIN_CONFIG{Name: "testnet", // testnet will always have last 3 bytes 0
|
||||
Network_ID: uuid.FromBytesOrNil([]byte{0x59, 0xd7, 0xf7, 0xe9, 0xdd, 0x48, 0xd5, 0xfd, 0x13, 0x0a, 0xf6, 0xe0, 0x70, 0x00, 0x00, 0x00}),
|
||||
Network_ID: uuid.FromBytesOrNil([]byte{0x59, 0xd7, 0xf7, 0xe9, 0xdd, 0x48, 0xd5, 0xfd, 0x13, 0x0a, 0xf6, 0xe0, 0x71, 0x00, 0x00, 0x00}),
|
||||
P2P_Default_Port: 40401,
|
||||
RPC_Default_Port: 40402,
|
||||
Wallet_RPC_Default_Port: 40403,
|
||||
|
@ -30,4 +30,5 @@ var Mainnet_seed_nodes = []string{
|
||||
// some seed node for testnet
|
||||
var Testnet_seed_nodes = []string{
|
||||
"68.183.12.117:40401",
|
||||
"167.99.145.53:40401",
|
||||
}
|
||||
|
@ -20,4 +20,4 @@ import "github.com/blang/semver/v4"
|
||||
|
||||
// right now it has to be manually changed
|
||||
// do we need to include git commitsha??
|
||||
var Version = semver.MustParse("3.4.87-1.DEROHE.STARGATE+24112021")
|
||||
var Version = semver.MustParse("3.4.89-1.DEROHE.STARGATE+22112021")
|
||||
|
2
vendor/github.com/creachadair/jrpc2/base.go
generated
vendored
2
vendor/github.com/creachadair/jrpc2/base.go
generated
vendored
@ -14,6 +14,8 @@ import (
|
||||
// no method is available to handle the request.
|
||||
type Assigner interface {
|
||||
// Assign returns the handler for the named method, or nil.
|
||||
// The implementation can obtain the complete request from ctx using the
|
||||
// jrpc2.InboundRequest function.
|
||||
Assign(ctx context.Context, method string) Handler
|
||||
|
||||
// Names returns a slice of all known method names for the assigner. The
|
||||
|
8
vendor/github.com/creachadair/jrpc2/channel/channel.go
generated
vendored
8
vendor/github.com/creachadair/jrpc2/channel/channel.go
generated
vendored
@ -1,6 +1,8 @@
|
||||
// Package channel defines a communications channel that can encode/transmit
|
||||
// and decode/receive data records with a configurable framing discipline, and
|
||||
// provides some simple framing implementations.
|
||||
// Package channel defines a basic communications channel.
|
||||
//
|
||||
// A Channel encodes/transmits and decodes/receives data records over an
|
||||
// unstructured stream, using a configurable framing discipline. This package
|
||||
// provides some basic framing implementations.
|
||||
//
|
||||
// Channels
|
||||
//
|
||||
|
4
vendor/github.com/creachadair/jrpc2/channel/json.go
generated
vendored
4
vendor/github.com/creachadair/jrpc2/channel/json.go
generated
vendored
@ -10,6 +10,10 @@ const bufSize = 4096
|
||||
// RawJSON is a framing that transmits and receives records on r and wc, in which
|
||||
// each record is defined by being a complete JSON value. No padding or other
|
||||
// separation is added.
|
||||
//
|
||||
// A RawJSON channel has no out-of-band framing, so the channel cannot usually
|
||||
// recover after a message that is not syntactically valid JSON. Applications
|
||||
// that need a channel to survive invalid JSON should avoid this framing.
|
||||
func RawJSON(r io.Reader, wc io.WriteCloser) Channel {
|
||||
return jsonc{wc: wc, dec: json.NewDecoder(r), buf: make([]byte, bufSize)}
|
||||
}
|
||||
|
24
vendor/github.com/creachadair/jrpc2/code/code.go
generated
vendored
24
vendor/github.com/creachadair/jrpc2/code/code.go
generated
vendored
@ -57,18 +57,16 @@ func (c Code) Err() error {
|
||||
return codeError(c)
|
||||
}
|
||||
|
||||
// Pre-defined standard error codes defined by the JSON-RPC specification.
|
||||
// Error codes from and including -32768 to -32000 are reserved for pre-defined
|
||||
// errors by the JSON-RPC specification. These constants cover the standard
|
||||
// codes and implementation-specific codes used by the jrpc2 module.
|
||||
const (
|
||||
ParseError Code = -32700 // Invalid JSON received by the server
|
||||
InvalidRequest Code = -32600 // The JSON sent is not a valid request object
|
||||
MethodNotFound Code = -32601 // The method does not exist or is unavailable
|
||||
InvalidParams Code = -32602 // Invalid method parameters
|
||||
InternalError Code = -32603 // Internal JSON-RPC error
|
||||
)
|
||||
ParseError Code = -32700 // [std] Invalid JSON received by the server
|
||||
InvalidRequest Code = -32600 // [std] The JSON sent is not a valid request object
|
||||
MethodNotFound Code = -32601 // [std] The method does not exist or is unavailable
|
||||
InvalidParams Code = -32602 // [std] Invalid method parameters
|
||||
InternalError Code = -32603 // [std] Internal JSON-RPC error
|
||||
|
||||
// The JSON-RPC 2.0 specification reserves the range -32000 to -32099 for
|
||||
// implementation-defined server errors. These are used by the jrpc2 package.
|
||||
const (
|
||||
NoError Code = -32099 // Denotes a nil error (used by FromError)
|
||||
SystemError Code = -32098 // Errors from the operating environment
|
||||
Cancelled Code = -32097 // Request cancelled (context.Canceled)
|
||||
@ -91,6 +89,10 @@ var stdError = map[Code]string{
|
||||
// Register adds a new Code value with the specified message string. This
|
||||
// function will panic if the proposed value is already registered with a
|
||||
// different string.
|
||||
//
|
||||
// Registering a code allows you to control the string returned by the String
|
||||
// method for the code value you specify. It is not necessary to register a
|
||||
// code before using it. An unregistered code renders a generic string.
|
||||
func Register(value int32, message string) Code {
|
||||
code := Code(value)
|
||||
if s, ok := stdError[code]; ok && s != message {
|
||||
@ -102,7 +104,7 @@ func Register(value int32, message string) Code {
|
||||
|
||||
// FromError returns a Code to categorize the specified error.
|
||||
// If err == nil, it returns code.NoError.
|
||||
// If err is an ErrCoder, it returns the reported code value.
|
||||
// If err is (or wraps) an ErrCoder, it returns the reported code value.
|
||||
// If err is context.Canceled, it returns code.Cancelled.
|
||||
// If err is context.DeadlineExceeded, it returns code.DeadlineExceeded.
|
||||
// Otherwise it returns code.SystemError.
|
||||
|
2
vendor/github.com/creachadair/jrpc2/doc.go
generated
vendored
2
vendor/github.com/creachadair/jrpc2/doc.go
generated
vendored
@ -84,7 +84,7 @@ To create a client we need a channel:
|
||||
|
||||
conn, err := net.Dial("tcp", "localhost:8080")
|
||||
...
|
||||
ch := channel.RawJSON(conn, conn)
|
||||
ch := channel.Line(conn, conn)
|
||||
cli := jrpc2.NewClient(ch, nil) // nil for default options
|
||||
|
||||
To send a single RPC, use the Call method:
|
||||
|
4
vendor/github.com/creachadair/jrpc2/error.go
generated
vendored
4
vendor/github.com/creachadair/jrpc2/error.go
generated
vendored
@ -47,10 +47,6 @@ var errEmptyMethod = &Error{Code: code.InvalidRequest, Message: "empty method na
|
||||
// errInvalidRequest is the error reported for an invalid request object or batch.
|
||||
var errInvalidRequest = &Error{Code: code.ParseError, Message: "invalid request value"}
|
||||
|
||||
// errChannelClosed is the error reported to a pending callback when the client
|
||||
// channel has closed before the call completed.
|
||||
var errChannelClosed = &Error{Code: code.Cancelled, Message: "client channel terminated"}
|
||||
|
||||
// errEmptyBatch is the error reported for an empty request batch.
|
||||
var errEmptyBatch = &Error{Code: code.InvalidRequest, Message: "empty request batch"}
|
||||
|
||||
|
46
vendor/github.com/creachadair/jrpc2/examples_test.go
generated
vendored
46
vendor/github.com/creachadair/jrpc2/examples_test.go
generated
vendored
@ -7,31 +7,23 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/creachadair/jrpc2"
|
||||
"github.com/creachadair/jrpc2/channel"
|
||||
"github.com/creachadair/jrpc2/code"
|
||||
"github.com/creachadair/jrpc2/handler"
|
||||
"github.com/creachadair/jrpc2/server"
|
||||
)
|
||||
|
||||
var (
|
||||
s *jrpc2.Server
|
||||
|
||||
ctx = context.Background()
|
||||
sch, cch = channel.Direct()
|
||||
cli = jrpc2.NewClient(cch, nil)
|
||||
|
||||
setup sync.Once
|
||||
)
|
||||
|
||||
type Msg struct {
|
||||
Text string `json:"msg"`
|
||||
}
|
||||
|
||||
func startServer() {
|
||||
setup.Do(func() {
|
||||
s = jrpc2.NewServer(handler.Map{
|
||||
func startServer() server.Local {
|
||||
return server.NewLocal(handler.Map{
|
||||
"Hello": handler.New(func(ctx context.Context) string {
|
||||
return "Hello, world!"
|
||||
}),
|
||||
@ -42,17 +34,17 @@ func startServer() {
|
||||
fmt.Println("Log:", msg.Text)
|
||||
return true, nil
|
||||
}),
|
||||
}, nil).Start(sch)
|
||||
})
|
||||
}, nil)
|
||||
}
|
||||
|
||||
func ExampleNewServer() {
|
||||
// Construct a new server with methods "Hello" and "Log".
|
||||
startServer()
|
||||
loc := startServer()
|
||||
defer loc.Close()
|
||||
|
||||
// We can query the server for its current status information, including a
|
||||
// list of its methods.
|
||||
si := s.ServerInfo()
|
||||
si := loc.Server.ServerInfo()
|
||||
|
||||
fmt.Println(strings.Join(si.Methods, "\n"))
|
||||
// Output:
|
||||
@ -62,10 +54,10 @@ func ExampleNewServer() {
|
||||
}
|
||||
|
||||
func ExampleClient_Call() {
|
||||
startServer()
|
||||
loc := startServer()
|
||||
defer loc.Close()
|
||||
|
||||
// var cli = jrpc2.NewClient(cch, nil)
|
||||
rsp, err := cli.Call(ctx, "Hello", nil)
|
||||
rsp, err := loc.Client.Call(ctx, "Hello", nil)
|
||||
if err != nil {
|
||||
log.Fatalf("Call: %v", err)
|
||||
}
|
||||
@ -79,11 +71,11 @@ func ExampleClient_Call() {
|
||||
}
|
||||
|
||||
func ExampleClient_CallResult() {
|
||||
startServer()
|
||||
loc := startServer()
|
||||
defer loc.Close()
|
||||
|
||||
// var cli = jrpc2.NewClient(cch, nil)
|
||||
var msg string
|
||||
if err := cli.CallResult(ctx, "Hello", nil, &msg); err != nil {
|
||||
if err := loc.Client.CallResult(ctx, "Hello", nil, &msg); err != nil {
|
||||
log.Fatalf("CallResult: %v", err)
|
||||
}
|
||||
fmt.Println(msg)
|
||||
@ -92,10 +84,10 @@ func ExampleClient_CallResult() {
|
||||
}
|
||||
|
||||
func ExampleClient_Batch() {
|
||||
startServer()
|
||||
loc := startServer()
|
||||
defer loc.Close()
|
||||
|
||||
// var cli = jrpc2.NewClient(cch, nil)
|
||||
rsps, err := cli.Batch(ctx, []jrpc2.Spec{
|
||||
rsps, err := loc.Client.Batch(ctx, []jrpc2.Spec{
|
||||
{Method: "Hello"},
|
||||
{Method: "Log", Params: Msg{"Sing it!"}, Notify: true},
|
||||
})
|
||||
@ -172,8 +164,10 @@ type strictParams struct {
|
||||
func (strictParams) DisallowUnknownFields() {}
|
||||
|
||||
func ExampleResponse_UnmarshalResult() {
|
||||
// var cli = jrpc2.NewClient(cch, nil)
|
||||
rsp, err := cli.Call(ctx, "Echo", []string{"alpha", "oscar", "kilo"})
|
||||
loc := startServer()
|
||||
defer loc.Close()
|
||||
|
||||
rsp, err := loc.Client.Call(ctx, "Echo", []string{"alpha", "oscar", "kilo"})
|
||||
if err != nil {
|
||||
log.Fatalf("Call: %v", err)
|
||||
}
|
||||
|
15
vendor/github.com/creachadair/jrpc2/handler/handler.go
generated
vendored
15
vendor/github.com/creachadair/jrpc2/handler/handler.go
generated
vendored
@ -88,6 +88,17 @@ func New(fn interface{}) Func {
|
||||
return fi.Wrap()
|
||||
}
|
||||
|
||||
// NewStrict acts as New, but enforces strict field checking on an argument of
|
||||
// struct type.
|
||||
func NewStrict(fn interface{}) Func {
|
||||
fi, err := Check(fn)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fi.strictFields = true
|
||||
return fi.Wrap()
|
||||
}
|
||||
|
||||
var (
|
||||
ctxType = reflect.TypeOf((*context.Context)(nil)).Elem() // type context.Context
|
||||
errType = reflect.TypeOf((*error)(nil)).Elem() // type error
|
||||
@ -355,8 +366,8 @@ func (o Obj) UnmarshalJSON(data []byte) error {
|
||||
if err := json.Unmarshal(data, &base); err != nil {
|
||||
return filterJSONError("decoding", "object", err)
|
||||
}
|
||||
for key, val := range base {
|
||||
arg, ok := o[key]
|
||||
for key, arg := range o {
|
||||
val, ok := base[key]
|
||||
if !ok {
|
||||
continue
|
||||
} else if err := json.Unmarshal(val, arg); err != nil {
|
||||
|
48
vendor/github.com/creachadair/jrpc2/handler/handler_test.go
generated
vendored
48
vendor/github.com/creachadair/jrpc2/handler/handler_test.go
generated
vendored
@ -7,6 +7,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/creachadair/jrpc2"
|
||||
"github.com/creachadair/jrpc2/code"
|
||||
"github.com/creachadair/jrpc2/handler"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
)
|
||||
@ -111,6 +112,26 @@ func TestPositional(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewStrict(t *testing.T) {
|
||||
type arg struct {
|
||||
A, B string
|
||||
}
|
||||
fn := handler.NewStrict(func(ctx context.Context, arg *arg) error { return nil })
|
||||
|
||||
req := mustParseRequest(t, `{
|
||||
"jsonrpc": "2.0",
|
||||
"id": 100,
|
||||
"method": "f",
|
||||
"params": {
|
||||
"A": "foo",
|
||||
"Z": 25
|
||||
}}`)
|
||||
rsp, err := fn(context.Background(), req)
|
||||
if got := code.FromError(err); got != code.InvalidParams {
|
||||
t.Errorf("Handler returned (%+v, %v), want InvalidParms", rsp, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Verify that the handling of pointer-typed arguments does not incorrectly
|
||||
// introduce another pointer indirection.
|
||||
func TestNew_pointerRegression(t *testing.T) {
|
||||
@ -120,18 +141,15 @@ func TestNew_pointerRegression(t *testing.T) {
|
||||
t.Logf("Got argument struct: %+v", got)
|
||||
return nil
|
||||
})
|
||||
req, err := jrpc2.ParseRequests([]byte(`{
|
||||
req := mustParseRequest(t, `{
|
||||
"jsonrpc": "2.0",
|
||||
"id": "foo",
|
||||
"method": "bar",
|
||||
"params":{
|
||||
"alpha": "xyzzy",
|
||||
"bravo": 23
|
||||
}}`))
|
||||
if err != nil {
|
||||
t.Fatalf("Parse request failed: %v", err)
|
||||
}
|
||||
if _, err := call.Handle(context.Background(), req[0]); err != nil {
|
||||
}}`)
|
||||
if _, err := call.Handle(context.Background(), req); err != nil {
|
||||
t.Errorf("Handle failed: %v", err)
|
||||
}
|
||||
want := argStruct{A: "xyzzy", B: 23}
|
||||
@ -165,11 +183,8 @@ func TestPositional_decode(t *testing.T) {
|
||||
{`{"jsonrpc":"2.0","id":6,"method":"add","params":{"unknown":"field"}}`, 0, true},
|
||||
}
|
||||
for _, test := range tests {
|
||||
req, err := jrpc2.ParseRequests([]byte(test.input))
|
||||
if err != nil {
|
||||
t.Fatalf("ParseRequests %#q: unexpected error: %v", test.input, err)
|
||||
}
|
||||
got, err := call(context.Background(), req[0])
|
||||
req := mustParseRequest(t, test.input)
|
||||
got, err := call(context.Background(), req)
|
||||
if !test.bad {
|
||||
if err != nil {
|
||||
t.Errorf("Call %#q: unexpected error: %v", test.input, err)
|
||||
@ -360,3 +375,14 @@ func TestObjUnmarshal(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func mustParseRequest(t *testing.T, text string) *jrpc2.Request {
|
||||
t.Helper()
|
||||
req, err := jrpc2.ParseRequests([]byte(text))
|
||||
if err != nil {
|
||||
t.Fatalf("ParseRequests: %v", err)
|
||||
} else if len(req) != 1 {
|
||||
t.Fatalf("Wrong number of requests: got %d, want 1", len(req))
|
||||
}
|
||||
return req[0]
|
||||
}
|
||||
|
2
vendor/github.com/creachadair/jrpc2/opts.go
generated
vendored
2
vendor/github.com/creachadair/jrpc2/opts.go
generated
vendored
@ -278,7 +278,7 @@ func (lg Logger) Printf(msg string, args ...interface{}) {
|
||||
}
|
||||
|
||||
// StdLogger adapts a *log.Logger to a Logger. If logger == nil, the returned
|
||||
// function sends logs to the default logger .
|
||||
// function sends logs to the default logger.
|
||||
func StdLogger(logger *log.Logger) Logger {
|
||||
if logger == nil {
|
||||
return func(text string) { log.Output(2, text) }
|
||||
|
10
vendor/github.com/creachadair/jrpc2/server.go
generated
vendored
10
vendor/github.com/creachadair/jrpc2/server.go
generated
vendored
@ -465,14 +465,15 @@ func (s *Server) pushReq(ctx context.Context, wantID bool, method string, params
|
||||
id := strconv.FormatInt(s.callID, 10)
|
||||
s.callID++
|
||||
|
||||
cbctx, cancel := context.WithCancel(ctx)
|
||||
jid = json.RawMessage(id)
|
||||
rsp = &Response{
|
||||
ch: make(chan *jmessage, 1),
|
||||
id: id,
|
||||
cancel: func() {},
|
||||
cancel: cancel,
|
||||
}
|
||||
s.call[id] = rsp
|
||||
go s.waitCallback(ctx, id, rsp)
|
||||
go s.waitCallback(cbctx, id, rsp)
|
||||
}
|
||||
|
||||
s.log("Posting server %s %q %s", kind, method, string(bits))
|
||||
@ -575,11 +576,8 @@ func (s *Server) stop(err error) {
|
||||
// Cancel any in-flight requests that made it out of the queue, and
|
||||
// terminate any pending callback invocations.
|
||||
for id, rsp := range s.call {
|
||||
rsp.ch <- &jmessage{
|
||||
ID: json.RawMessage(id),
|
||||
E: errChannelClosed,
|
||||
}
|
||||
delete(s.call, id)
|
||||
rsp.cancel()
|
||||
}
|
||||
for id, cancel := range s.used {
|
||||
cancel()
|
||||
|
2
vendor/github.com/creachadair/jrpc2/tools/examples/client/client.go
generated
vendored
2
vendor/github.com/creachadair/jrpc2/tools/examples/client/client.go
generated
vendored
@ -65,7 +65,7 @@ func main() {
|
||||
log.Printf("Connected to %v", conn.RemoteAddr())
|
||||
|
||||
// Start up the client, and enable logging to stderr.
|
||||
cli := jrpc2.NewClient(channel.RawJSON(conn, conn), &jrpc2.ClientOptions{
|
||||
cli := jrpc2.NewClient(channel.Line(conn, conn), &jrpc2.ClientOptions{
|
||||
OnNotify: func(req *jrpc2.Request) {
|
||||
var params json.RawMessage
|
||||
req.UnmarshalParams(¶ms)
|
||||
|
2
vendor/github.com/creachadair/jrpc2/tools/examples/server/server.go
generated
vendored
2
vendor/github.com/creachadair/jrpc2/tools/examples/server/server.go
generated
vendored
@ -96,7 +96,7 @@ func main() {
|
||||
log.Fatalln("Listen:", err)
|
||||
}
|
||||
log.Printf("Listening at %v...", lst.Addr())
|
||||
acc := server.NetAccepter(lst, channel.RawJSON)
|
||||
acc := server.NetAccepter(lst, channel.Line)
|
||||
server.Loop(acc, server.Static(mux), &server.LoopOptions{
|
||||
ServerOptions: &jrpc2.ServerOptions{
|
||||
Logger: jrpc2.StdLogger(nil),
|
||||
|
4
vendor/github.com/creachadair/jrpc2/tools/go.mod
generated
vendored
4
vendor/github.com/creachadair/jrpc2/tools/go.mod
generated
vendored
@ -3,8 +3,8 @@ module github.com/creachadair/jrpc2/tools
|
||||
go 1.17
|
||||
|
||||
require (
|
||||
github.com/creachadair/jrpc2 v0.30.1
|
||||
github.com/creachadair/wschannel v0.0.0-20210930050814-ee1a57283ef3
|
||||
github.com/creachadair/jrpc2 v0.30.3
|
||||
github.com/creachadair/wschannel v0.0.0-20211118152247-10d58f4f0def
|
||||
)
|
||||
|
||||
require (
|
||||
|
9
vendor/github.com/creachadair/jrpc2/tools/go.sum
generated
vendored
9
vendor/github.com/creachadair/jrpc2/tools/go.sum
generated
vendored
@ -1,8 +1,7 @@
|
||||
github.com/creachadair/jrpc2 v0.26.0/go.mod h1:w+GXZGc+NwsH0xsUOgeLBIIRM0jBOSTXhv28KaWGRZU=
|
||||
github.com/creachadair/jrpc2 v0.30.1 h1:brsyJY1US3f5mxS3IaYoc8kH2O1MNcWUKiBmGswUeE8=
|
||||
github.com/creachadair/jrpc2 v0.30.1/go.mod h1:w+GXZGc+NwsH0xsUOgeLBIIRM0jBOSTXhv28KaWGRZU=
|
||||
github.com/creachadair/wschannel v0.0.0-20210930050814-ee1a57283ef3 h1:b0LJF4h+tv81wui0UKrszHi+yny5B/UJA10bHimYy0Y=
|
||||
github.com/creachadair/wschannel v0.0.0-20210930050814-ee1a57283ef3/go.mod h1:ZW4LjPekGnPGBDEgssmCLAOIObRDGv2SQay/pT+5ZwM=
|
||||
github.com/creachadair/jrpc2 v0.30.3 h1:fz8xYfTmIgxJXvr9HAoz0XBOpNklyixE7Hnh6iQP/4o=
|
||||
github.com/creachadair/jrpc2 v0.30.3/go.mod h1:w+GXZGc+NwsH0xsUOgeLBIIRM0jBOSTXhv28KaWGRZU=
|
||||
github.com/creachadair/wschannel v0.0.0-20211118152247-10d58f4f0def h1:FV0vHCqItsi0b3LwaEKyxj0su3VKdvbenCOkXnCAXnI=
|
||||
github.com/creachadair/wschannel v0.0.0-20211118152247-10d58f4f0def/go.mod h1:/9Csuxj8r9h0YXexL0WmkahIhd85BleYWz7nt42ZgDc=
|
||||
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||
|
@ -280,7 +280,7 @@ rebuild_tx:
|
||||
if tx.SCDATA.Has(rpc.SCACTION, rpc.DataUint64) {
|
||||
if rpc.SC_INSTALL == rpc.SC_ACTION(tx.SCDATA.Value(rpc.SCACTION, rpc.DataUint64).(uint64)) {
|
||||
txid := tx.GetHash()
|
||||
if txid[31] < 0x80 { // last byte should be more than 0x80
|
||||
if txid[0] < 0x80 || txid[31] < 0x80 { // last byte should be more than 0x80
|
||||
if retry_count <= 20 {
|
||||
//fmt.Printf("rebuilding tx %s retry_count %d\n", txid, retry_count)
|
||||
goto rebuild_tx
|
||||
|
Loading…
Reference in New Issue
Block a user