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 }