github.com/uuosio/chaintester@v0.0.0-20230731100329-1f6fad7372e5/server.go (about)

     1  package chaintester
     2  
     3  import (
     4  	"context"
     5  	"crypto/tls"
     6  	"encoding/binary"
     7  	"fmt"
     8  
     9  	"github.com/uuosio/chaintester/interfaces"
    10  
    11  	_ "unsafe"
    12  
    13  	"github.com/apache/thrift/lib/go/thrift"
    14  )
    15  
    16  var g_VMAPI *interfaces.ApplyClient
    17  var g_InApply = false
    18  
    19  func SetInApply(inApply bool) {
    20  	g_InApply = inApply
    21  }
    22  
    23  func IsInApply() bool {
    24  	return g_InApply
    25  }
    26  
    27  func InitVMAPI() {
    28  	if g_VMAPI != nil {
    29  		return
    30  	}
    31  
    32  	var err error
    33  	address := fmt.Sprintf("%s:%s", GetDebuggerConfig().VMAPIServerAddress, GetDebuggerConfig().VMAPIServerPort)
    34  	g_VMAPI, err = NewVMAPIClient(address)
    35  	if err != nil {
    36  		panic(err)
    37  	}
    38  }
    39  
    40  func GetVMAPI() *interfaces.ApplyClient {
    41  	if g_VMAPI != nil {
    42  		if !IsInApply() {
    43  			panic("error: call vm api function out of apply context!")
    44  		}
    45  		return g_VMAPI
    46  	}
    47  
    48  	var err error
    49  	address := fmt.Sprintf("%s:%s", GetDebuggerConfig().VMAPIServerAddress, GetDebuggerConfig().VMAPIServerPort)
    50  	g_VMAPI, err = NewVMAPIClient(address)
    51  	if err != nil {
    52  		panic(err)
    53  	}
    54  	return g_VMAPI
    55  }
    56  
    57  var g_VMAPITransport thrift.TTransport
    58  
    59  func CloseVMAPI() {
    60  	g_VMAPITransport.Close()
    61  }
    62  
    63  func NewProtocol(addr string) (thrift.TProtocol, thrift.TProtocol, error) {
    64  
    65  	protocolFactory := thrift.NewTBinaryProtocolFactoryConf(nil)
    66  	// protocolFactory := thrift.NewTCompactProtocolFactoryConf(nil)
    67  	transportFactory := thrift.NewTBufferedTransportFactory(8192)
    68  
    69  	cfg := &thrift.TConfiguration{
    70  		TLSConfig: &tls.Config{
    71  			InsecureSkipVerify: true,
    72  		},
    73  	}
    74  	g_VMAPITransport = thrift.NewTSocketConf(addr, cfg)
    75  	g_VMAPITransport, err := transportFactory.GetTransport(g_VMAPITransport)
    76  	if err != nil {
    77  		return nil, nil, err
    78  	}
    79  	// defer transport.Close()
    80  	if err := g_VMAPITransport.Open(); err != nil {
    81  		return nil, nil, err
    82  	}
    83  	iprot := protocolFactory.GetProtocol(g_VMAPITransport)
    84  	oprot := protocolFactory.GetProtocol(g_VMAPITransport)
    85  	return iprot, oprot, nil
    86  }
    87  
    88  func NewVMAPIClient(addr string) (*interfaces.ApplyClient, error) {
    89  	iprot, oprot, err := NewProtocol(addr)
    90  	if err != nil {
    91  		return nil, err
    92  	}
    93  	// transport.Close()
    94  	// oprot.Transport().Close()
    95  	return interfaces.NewApplyClient(NewIPCClient(iprot, oprot)), nil
    96  }
    97  
    98  type ApplyRequestHandler struct {
    99  }
   100  
   101  func NewApplyRequestHandler() *ApplyRequestHandler {
   102  	return &ApplyRequestHandler{}
   103  }
   104  
   105  //go:linkname callNativeApply main.native_apply
   106  func callNativeApply(receiver uint64, firstReceiver uint64, action uint64)
   107  
   108  func getUint64(value *interfaces.Uint64) uint64 {
   109  	return binary.LittleEndian.Uint64(value.RawValue)
   110  }
   111  
   112  var g_ChainTesterApplyMap = make(map[int32]map[string]func(uint64, uint64, uint64))
   113  
   114  func (p *ApplyRequestHandler) ApplyRequest(ctx context.Context, receiver *interfaces.Uint64, firstReceiver *interfaces.Uint64, action *interfaces.Uint64, chainTesterId int32) (_r int32, _err error) {
   115  	// fmt.Println("+++++++ApplyRequest called!")
   116  	defer func() {
   117  		if err := recover(); err != nil {
   118  			_, ok := err.(*AssertError)
   119  			if ok {
   120  				// fmt.Printf("recovered from assertion error: %v", _r)
   121  			} else {
   122  				// fmt.Printf("recovered error: %s", err)
   123  				_err = fmt.Errorf("%v", err)
   124  				_r = -1
   125  			}
   126  			GetVMAPI().EndApply(ctx)
   127  			SetInApply(false)
   128  		}
   129  	}()
   130  
   131  	_receiver := getUint64(receiver)
   132  	_firstReceiver := getUint64(firstReceiver)
   133  	_action := getUint64(action)
   134  
   135  	SetInApply(true)
   136  	if applyMap, ok := g_ChainTesterApplyMap[chainTesterId]; ok {
   137  		if apply, ok := applyMap[N2S(_receiver)]; ok {
   138  			apply(_receiver, _firstReceiver, _action)
   139  		}
   140  	}
   141  	GetVMAPI().EndApply(ctx)
   142  	SetInApply(false)
   143  
   144  	_r = -1
   145  	_err = nil
   146  	return
   147  }
   148  
   149  func (p *ApplyRequestHandler) ApplyEnd(ctx context.Context, chainTesterId int32) (_r int32, _err error) {
   150  	// fmt.Println("+++++++ApplyEnd")
   151  	GetApplyRequestServer().server.EndProcessRequests()
   152  	return 1, nil
   153  }
   154  
   155  type ApplyRequestServer struct {
   156  	server *SimpleIPCServer
   157  }
   158  
   159  func NewApplyRequestServer() *ApplyRequestServer {
   160  	var transport thrift.TServerTransport
   161  	var err error
   162  	addr := fmt.Sprintf("%s:%s", g_DebuggerConfig.ApplyRequestServerAddress, g_DebuggerConfig.ApplyRequestServerPort)
   163  	transport, err = thrift.NewTServerSocket(addr)
   164  	if err != nil {
   165  		return nil
   166  	}
   167  
   168  	handler := NewApplyRequestHandler()
   169  	processor := interfaces.NewApplyRequestProcessor(handler)
   170  
   171  	protocolFactory := thrift.NewTBinaryProtocolFactoryConf(nil)
   172  	// protocolFactory := thrift.NewTCompactProtocolFactoryConf(nil)
   173  
   174  	transportFactory := thrift.NewTBufferedTransportFactory(8192)
   175  
   176  	server := &ApplyRequestServer{
   177  		server: NewSimpleIPCServer4(processor, transport, transportFactory, protocolFactory),
   178  	}
   179  
   180  	err = server.server.Listen()
   181  	if err != nil {
   182  		panic(err)
   183  	}
   184  	return server
   185  }
   186  
   187  func (server *ApplyRequestServer) AcceptOnce() (int32, error) {
   188  	return server.server.AcceptOnce()
   189  }
   190  
   191  func (server *ApplyRequestServer) Serve() (int32, error) {
   192  	// fmt.Println("+++++++ApplyRequestServer:ProcessRequests")
   193  	return server.server.ProcessRequests()
   194  }
   195  
   196  func (server *ApplyRequestServer) Stop() error {
   197  	fmt.Println("+++++++ApplyRequestServer:Stop")
   198  	return server.server.Stop()
   199  }