Skip to content

Instantly share code, notes, and snippets.

@filinvadim
Last active April 5, 2018 13:41
Show Gist options
  • Save filinvadim/9500d2eadad816dd760b3ac388513d87 to your computer and use it in GitHub Desktop.
Save filinvadim/9500d2eadad816dd760b3ac388513d87 to your computer and use it in GitHub Desktop.
Acces to Go-Ethereum IPC socket
var defaultPaths = []string {
"/.ethereum/geth.ipc", //unix
"/Library/Ethereum/geth.ipc", //macos
"\\\\.\\pipe\\geth.ipc", //win
}
type SocketResolver interface {
GetSocket() string
Connect()
Write(string []byte)
Read()
Close()
GetResponse() []byte
}
type IPCSocket struct {
path string
connect net.Conn
response []byte
}
// maybe we should abstract from returning specific socket by
// assigning priority levels to those connection methods and
// trying connect to each other socket in priority order
func NewIPCSocket(path string) SocketResolver {
return &IPCSocket{path: path}
}
func (i *IPCSocket) GetSocket() string {
return i.path
}
func (i *IPCSocket) GetResponse() []byte {
return i.response
}
func (i *IPCSocket) Connect() {
var err error
i.connect, err = net.Dial("unix", i.path)
if err == nil {
log.Info(i.connect)
return
}
log.Warningf("fail to find given IPC socket: %#v", err)
for _, path := range defaultPaths {
absPath := getAbsIPCPath(path)
log.Infof("connecting to default paths: %s", absPath)
i.connect, err = net.Dial("unix", absPath)
if err == nil {
return
}
}
log.Panicf("can't find IPC socket: %v", err)
}
func (i *IPCSocket) Write(ethMethod []byte) {
num, err := i.connect.Write(ethMethod)
if err != nil {
log.Warningf("fail while writing to IPC socket: %v", err)
return
}
if len(ethMethod) != num {
log.Warnf("after writing to IPC socket bytes lost: %i", (len(ethMethod) - num))
}
}
func (i *IPCSocket) Read() {
buffer := bytes.Buffer{}
defer buffer.Reset()
for {
reader := bufio.NewReader(i.connect)
line, prefix, err := reader.ReadLine()
if err != nil {
log.Warningf("error: can't read form socket:", err)
}
buffer.Write(line)
if !prefix {
break
}
}
if len(buffer.Bytes()) != 0 {
i.response = buffer.Bytes()
return
}
log.Info("empty response from socket")
}
func (i *IPCSocket) Close() {
closer.Bind(func() {
i.connect.Close()
})
}
func getAbsIPCPath (path string) string {
var absPath string
curUsr, err := user.Current()
if err != nil {
log.Warningf("can't obtain <home> path: %v", err)
return ""
}
if runtime.GOOS != "windows" {
absPath = curUsr.HomeDir + path
} else {
absPath = filepath.Clean(path)
}
return absPath
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment