lukechampine/us

Context based cancellation

jkawamoto opened this issue · 9 comments

In PseudoFS, the user should be responsible for cancellation because the user could cancel writing contents to PseudoFile. However, in PseudoKV, currently, there is no way to cancel uploading/downloading. We can, for example, close the reader that is passed to Put method during upload but it still doesn't stop actual uploads. So, PseudoKV would be better to support context-based cancellation.

Related to #67.

This also needs #23.

Implemented in 91437d0, let me know if more work is needed here.

@lukechampine Thanks for that update. Unfortunately, it looks like there are bugs and go test ./... -race fails with this error:

fatal error: checkptr: converted pointer straddles multiple allocations

goroutine 3102 [running]:
runtime.throw(0x15ad5f6, 0x3a)
        /usr/local/Cellar/go/1.15.2/libexec/src/runtime/panic.go:1116 +0x72 fp=0xc004e250d0 sp=0xc004e250a0 pc=0x10794f2
runtime.checkptrAlignment(0xc00071bb90, 0x1566da0, 0x1)
        /usr/local/Cellar/go/1.15.2/libexec/src/runtime/checkptr.go:20 +0xc9 fp=0xc004e25100 sp=0xc004e250d0 pc=0x1049329
gitlab.com/NebulousLabs/bolt.(*Bucket).write(0xc004e25270, 0x0, 0x0, 0x0)
        /Users/junpei/pkg/mod/gitlab.com/!nebulous!labs/bolt@v1.4.0/bucket.go:624 +0x15f fp=0xc004e25168 sp=0xc004e25100 pc=0x1330b7f
gitlab.com/NebulousLabs/bolt.(*Bucket).CreateBucket(0xc001cf8018, 0x1c02718, 0x5, 0x5, 0x10b3f8c, 0x10c93bf, 0xc001cf01a0)
        /Users/junpei/pkg/mod/gitlab.com/!nebulous!labs/bolt@v1.4.0/bucket.go:181 +0x32d fp=0xc004e25320 sp=0xc004e25168 pc=0x132de8d
gitlab.com/NebulousLabs/bolt.(*Bucket).CreateBucketIfNotExists(0xc001cf8018, 0x1c02718, 0x5, 0x5, 0x0, 0xc004e25f08, 0x0)
        /Users/junpei/pkg/mod/gitlab.com/!nebulous!labs/bolt@v1.4.0/bucket.go:199 +0x5e fp=0xc004e25388 sp=0xc004e25320 pc=0x132e31e
gitlab.com/NebulousLabs/bolt.(*Tx).CreateBucketIfNotExists(...)
        /Users/junpei/pkg/mod/gitlab.com/!nebulous!labs/bolt@v1.4.0/tx.go:115
lukechampine.com/us/renter/renterutil.NewBoltMetaDB.func1(0xc001cf8000, 0xc00011dc01, 0xc001cf8000)
        /Users/junpei/src/github.com/lukechampine/us/renter/renterutil/metadb.go:393 +0x1bb fp=0xc004e25450 sp=0xc004e25388 pc=0x14e05db
gitlab.com/NebulousLabs/bolt.(*DB).Update(0xc001cf0000, 0x15b56b0, 0x0, 0x0)
        /Users/junpei/pkg/mod/gitlab.com/!nebulous!labs/bolt@v1.4.0/db.go:677 +0xf1 fp=0xc004e254f8 sp=0xc004e25450 pc=0x13394d1
lukechampine.com/us/renter/renterutil.NewBoltMetaDB(0xc001cd82d0, 0x4c, 0x2, 0xc001cd82d0, 0x4c)
        /Users/junpei/src/github.com/lukechampine/us/renter/renterutil/metadb.go:386 +0x10b fp=0xc004e25590 sp=0xc004e254f8 pc=0x14b67cb
lukechampine.com/us/renter/renterutil.createTestingKV(0x162aa40, 0xc0003d6300, 0x2, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
        /Users/junpei/src/github.com/lukechampine/us/renter/renterutil/kv_test.go:48 +0xee5 fp=0xc004e25b80 sp=0xc004e25590 pc=0x14ce185
lukechampine.com/us/renter/renterutil.TestKVPutGet(0xc0003d6300)
        /Users/junpei/src/github.com/lukechampine/us/renter/renterutil/kv_test.go:73 +0x94 fp=0xc004e25ed0 sp=0xc004e25b80 pc=0x14ce514
testing.tRunner(0xc0003d6300, 0x15b5788)
        /usr/local/Cellar/go/1.15.2/libexec/src/testing/testing.go:1127 +0x203 fp=0xc004e25fd0 sp=0xc004e25ed0 pc=0x11b44e3
runtime.goexit()
        /usr/local/Cellar/go/1.15.2/libexec/src/runtime/asm_amd64.s:1374 +0x1 fp=0xc004e25fd8 sp=0xc004e25fd0 pc=0x10b24a1
created by testing.(*T).Run
        /usr/local/Cellar/go/1.15.2/libexec/src/testing/testing.go:1178 +0x797

goroutine 1 [chan receive]:
testing.(*T).Run(0xc000106480, 0x159c0bb, 0xc, 0x15b5788, 0x1)
        /usr/local/Cellar/go/1.15.2/libexec/src/testing/testing.go:1179 +0x7cf
testing.runTests.func1(0xc000106480)
        /usr/local/Cellar/go/1.15.2/libexec/src/testing/testing.go:1449 +0xa7
testing.tRunner(0xc000106480, 0xc00016fcc8)
        /usr/local/Cellar/go/1.15.2/libexec/src/testing/testing.go:1127 +0x203
testing.runTests(0xc00012cae0, 0x1c63280, 0x14, 0x14, 0xbfd8717dccf736c0, 0x8bb2fd00fe, 0x1c72000, 0xc000158980)
        /usr/local/Cellar/go/1.15.2/libexec/src/testing/testing.go:1447 +0x5ab
testing.(*M).Run(0xc0001be080, 0x0)
        /usr/local/Cellar/go/1.15.2/libexec/src/testing/testing.go:1357 +0x4ec
main.main()
        _testmain.go:95 +0x237

goroutine 3948 [IO wait]:
internal/poll.runtime_pollWait(0xa32de38, 0x72, 0x0)
        /usr/local/Cellar/go/1.15.2/libexec/src/runtime/netpoll.go:220 +0x55
internal/poll.(*pollDesc).wait(0xc0002e6218, 0x72, 0x0, 0x0, 0x1598888)
        /usr/local/Cellar/go/1.15.2/libexec/src/internal/poll/fd_poll_runtime.go:87 +0xe6
internal/poll.(*pollDesc).waitRead(...)
        /usr/local/Cellar/go/1.15.2/libexec/src/internal/poll/fd_poll_runtime.go:92
internal/poll.(*FD).Accept(0xc0002e6200, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
        /usr/local/Cellar/go/1.15.2/libexec/src/internal/poll/fd_unix.go:394 +0x2fe
net.(*netFD).accept(0xc0002e6200, 0x37e11d600, 0x0, 0x0)
        /usr/local/Cellar/go/1.15.2/libexec/src/net/fd_unix.go:172 +0x58
net.(*TCPListener).accept(0xc004d19ae0, 0xc00011dc18, 0x0, 0x0)
        /usr/local/Cellar/go/1.15.2/libexec/src/net/tcpsock_posix.go:139 +0x50
net.(*TCPListener).Accept(0xc004d19ae0, 0x15b55d8, 0xc0007b4280, 0x1629660, 0xc00011dc18)
        /usr/local/Cellar/go/1.15.2/libexec/src/net/tcpsock.go:261 +0x8e
lukechampine.com/us/internal/ghost.(*Host).listen(0xc0007b4280, 0xc0001783a0, 0x20)
        /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:54 +0x88
created by lukechampine.com/us/internal/ghost.New
        /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:83 +0x2d1

goroutine 3951 [IO wait]:
internal/poll.runtime_pollWait(0xa32dc78, 0x72, 0x0)
        /usr/local/Cellar/go/1.15.2/libexec/src/runtime/netpoll.go:220 +0x55
internal/poll.(*pollDesc).wait(0xc0002e6618, 0x72, 0x0, 0x0, 0x1598888)
        /usr/local/Cellar/go/1.15.2/libexec/src/internal/poll/fd_poll_runtime.go:87 +0xe6
internal/poll.(*pollDesc).waitRead(...)
        /usr/local/Cellar/go/1.15.2/libexec/src/internal/poll/fd_poll_runtime.go:92
internal/poll.(*FD).Accept(0xc0002e6600, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
        /usr/local/Cellar/go/1.15.2/libexec/src/internal/poll/fd_unix.go:394 +0x2fe
net.(*netFD).accept(0xc0002e6600, 0x37e11d600, 0x0, 0x0)
        /usr/local/Cellar/go/1.15.2/libexec/src/net/fd_unix.go:172 +0x58
net.(*TCPListener).accept(0xc004d19ce0, 0xc004c67890, 0x0, 0x0)
        /usr/local/Cellar/go/1.15.2/libexec/src/net/tcpsock_posix.go:139 +0x50
net.(*TCPListener).Accept(0xc004d19ce0, 0x15b55d8, 0xc0007b4550, 0x1629660, 0xc004c67890)
        /usr/local/Cellar/go/1.15.2/libexec/src/net/tcpsock.go:261 +0x8e
lukechampine.com/us/internal/ghost.(*Host).listen(0xc0007b4550, 0xc000178520, 0x20)
        /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:54 +0x88
created by lukechampine.com/us/internal/ghost.New
        /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:83 +0x2d1

goroutine 3970 [IO wait]:
internal/poll.runtime_pollWait(0xa32d9d8, 0x72, 0x1622840)
        /usr/local/Cellar/go/1.15.2/libexec/src/runtime/netpoll.go:220 +0x55
internal/poll.(*pollDesc).wait(0xc0002e6798, 0x72, 0xc001cec000, 0x8, 0x1bf8)
        /usr/local/Cellar/go/1.15.2/libexec/src/internal/poll/fd_poll_runtime.go:87 +0xe6
internal/poll.(*pollDesc).waitRead(...)
        /usr/local/Cellar/go/1.15.2/libexec/src/internal/poll/fd_poll_runtime.go:92
internal/poll.(*FD).Read(0xc0002e6780, 0xc001cec000, 0x8, 0x1bf8, 0x0, 0x0, 0x0)
        /usr/local/Cellar/go/1.15.2/libexec/src/internal/poll/fd_unix.go:159 +0x24f
net.(*netFD).Read(0xc0002e6780, 0xc001cec000, 0x8, 0x1bf8, 0xc0000f66f8, 0xc0000f8408, 0xc0000f8400)
        /usr/local/Cellar/go/1.15.2/libexec/src/net/fd_posix.go:55 +0x66
net.(*conn).Read(0xc004c67890, 0xc001cec000, 0x8, 0x1bf8, 0x10b3b62, 0x119887f, 0xc00009c138)
        /usr/local/Cellar/go/1.15.2/libexec/src/net/net.go:182 +0xec
io.(*LimitedReader).Read(0xc00009c160, 0xc001cec000, 0x8, 0x1bf8, 0x0, 0x37659ad718625b5e, 0x4e41547c75badb94)
        /usr/local/Cellar/go/1.15.2/libexec/src/io/io.go:455 +0xc8
bytes.(*Buffer).ReadFrom(0xc00009c138, 0x1621a80, 0xc00009c160, 0xc002a4f998, 0xb2c0554, 0xc000052d80)
        /usr/local/Cellar/go/1.15.2/libexec/src/bytes/buffer.go:204 +0x159
lukechampine.com/us/renterhost.(*objBuffer).copyN(0xc00009c138, 0xa2c5038, 0xc004c67890, 0x8, 0xc004c67890, 0xc0002e6780)
        /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:136 +0xc5
lukechampine.com/us/renterhost.(*Session).readMessage(0xc00009c100, 0x1626860, 0xc00373af50, 0x1000, 0x15ac8db0, 0xff61d1bc)
        /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:152 +0x1d3
lukechampine.com/us/renterhost.(*Session).ReadID(0xc00009c100, 0x34630b8a000, 0x0, 0x0, 0x0)
        /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:194 +0x108
lukechampine.com/us/internal/ghost.(*Host).handleConn(0xc0007b4550, 0x1629660, 0xc004c67890, 0x0, 0x0)
        /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:56 +0x9a5
lukechampine.com/us/internal/ghost.(*Host).listen.func1(0xc0007b4550, 0x1629660, 0xc004c67890)
        /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:59 +0x54
created by lukechampine.com/us/internal/ghost.(*Host).listen
        /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:58 +0x5d

goroutine 3103 [IO wait]:
internal/poll.runtime_pollWait(0xa32dd58, 0x72, 0x0)
        /usr/local/Cellar/go/1.15.2/libexec/src/runtime/netpoll.go:220 +0x55
internal/poll.(*pollDesc).wait(0xc0001be318, 0x72, 0x0, 0x0, 0x1598888)
        /usr/local/Cellar/go/1.15.2/libexec/src/internal/poll/fd_poll_runtime.go:87 +0xe6
internal/poll.(*pollDesc).waitRead(...)
        /usr/local/Cellar/go/1.15.2/libexec/src/internal/poll/fd_poll_runtime.go:92
internal/poll.(*FD).Accept(0xc0001be300, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
        /usr/local/Cellar/go/1.15.2/libexec/src/internal/poll/fd_unix.go:394 +0x2fe
net.(*netFD).accept(0xc0001be300, 0x37e11d600, 0x0, 0x0)
        /usr/local/Cellar/go/1.15.2/libexec/src/net/fd_unix.go:172 +0x58
net.(*TCPListener).accept(0xc005ea0080, 0xc00011dc10, 0x0, 0x0)
        /usr/local/Cellar/go/1.15.2/libexec/src/net/tcpsock_posix.go:139 +0x50
net.(*TCPListener).Accept(0xc005ea0080, 0x15b55d8, 0xc00070c140, 0x1629660, 0xc00011dc10)
        /usr/local/Cellar/go/1.15.2/libexec/src/net/tcpsock.go:261 +0x8e
lukechampine.com/us/internal/ghost.(*Host).listen(0xc00070c140, 0xc0023840a0, 0x20)
        /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:54 +0x88
created by lukechampine.com/us/internal/ghost.New
        /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:83 +0x2d1

bolt fails the new checkptr check in Go 1.15. You can disable the check with -gcflags=all=-d=checkptr=0.

The latest version of bolt probably works by now, so I'll see about updating it.

I upgraded gitlab.com/NebulousLabs/bolt to v1.4.4 and now get these errors:

==================
WARNING: DATA RACE
Write at 0x00c0000a63e8 by goroutine 88:
  lukechampine.com/us/renterhost.(*Session).setErr()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:77 +0xbd
  lukechampine.com/us/renterhost.(*Session).readMessage()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:153 +0xb6b
  lukechampine.com/us/renterhost.(*Session).ReadResponse()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:224 +0x139
  lukechampine.com/us/internal/ghost.(*Host).rpcRead.func1()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:574 +0xca

Previous read at 0x00c0000a63e8 by goroutine 55:
  lukechampine.com/us/renterhost.(*Session).writeMessage()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:113 +0x66
  lukechampine.com/us/renterhost.(*Session).WriteResponse()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:216 +0x184
  lukechampine.com/us/internal/ghost.(*Host).rpcRead()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:697 +0x167e
  lukechampine.com/us/internal/ghost.(*Host).rpcRead-fm()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:560 +0x4b
  lukechampine.com/us/internal/ghost.(*Host).handleConn()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:66 +0xaad
  lukechampine.com/us/internal/ghost.(*Host).listen.func1()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:59 +0x53

Goroutine 88 (running) created at:
  lukechampine.com/us/internal/ghost.(*Host).rpcRead()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:572 +0x19b
  lukechampine.com/us/internal/ghost.(*Host).rpcRead-fm()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:560 +0x4b
  lukechampine.com/us/internal/ghost.(*Host).handleConn()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:66 +0xaad
  lukechampine.com/us/internal/ghost.(*Host).listen.func1()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:59 +0x53

Goroutine 55 (running) created at:
  lukechampine.com/us/internal/ghost.(*Host).listen()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:58 +0x5c
==================
==================
WARNING: DATA RACE
Write at 0x00c0010fa0e8 by goroutine 114:
  lukechampine.com/us/renterhost.(*Session).setErr()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:77 +0xbd
  lukechampine.com/us/renterhost.(*Session).readMessage()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:153 +0xb6b
  lukechampine.com/us/renterhost.(*Session).ReadResponse()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:224 +0x139
  lukechampine.com/us/internal/ghost.(*Host).rpcRead.func1()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:574 +0xca

Previous read at 0x00c0010fa0e8 by goroutine 161:
  lukechampine.com/us/renterhost.(*Session).writeMessage()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:113 +0x66
  lukechampine.com/us/renterhost.(*Session).WriteResponse()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:216 +0x184
  lukechampine.com/us/internal/ghost.(*Host).rpcRead()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:697 +0x167e
  lukechampine.com/us/internal/ghost.(*Host).rpcRead-fm()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:560 +0x4b
  lukechampine.com/us/internal/ghost.(*Host).handleConn()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:66 +0xaad
  lukechampine.com/us/internal/ghost.(*Host).listen.func1()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:59 +0x53

Goroutine 114 (running) created at:
  lukechampine.com/us/internal/ghost.(*Host).rpcRead()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:572 +0x19b
  lukechampine.com/us/internal/ghost.(*Host).rpcRead-fm()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:560 +0x4b
  lukechampine.com/us/internal/ghost.(*Host).handleConn()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:66 +0xaad
  lukechampine.com/us/internal/ghost.(*Host).listen.func1()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:59 +0x53

Goroutine 161 (running) created at:
  lukechampine.com/us/internal/ghost.(*Host).listen()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:58 +0x5c
==================
==================
WARNING: DATA RACE
Write at 0x00c0009da2e8 by goroutine 68:
  lukechampine.com/us/renterhost.(*Session).setErr()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:77 +0xbd
  lukechampine.com/us/renterhost.(*Session).readMessage()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:153 +0xb6b
  lukechampine.com/us/renterhost.(*Session).ReadResponse()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:224 +0x139
  lukechampine.com/us/internal/ghost.(*Host).rpcRead.func1()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:574 +0xca

Previous read at 0x00c0009da2e8 by goroutine 138:
  lukechampine.com/us/renterhost.(*Session).writeMessage()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:113 +0x66
  lukechampine.com/us/renterhost.(*Session).WriteResponse()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:216 +0x184
  lukechampine.com/us/internal/ghost.(*Host).rpcRead()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:697 +0x167e
  lukechampine.com/us/internal/ghost.(*Host).rpcRead-fm()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:560 +0x4b
  lukechampine.com/us/internal/ghost.(*Host).handleConn()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:66 +0xaad
  lukechampine.com/us/internal/ghost.(*Host).listen.func1()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:59 +0x53

Goroutine 68 (running) created at:
  lukechampine.com/us/internal/ghost.(*Host).rpcRead()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:572 +0x19b
  lukechampine.com/us/internal/ghost.(*Host).rpcRead-fm()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:560 +0x4b
  lukechampine.com/us/internal/ghost.(*Host).handleConn()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:66 +0xaad
  lukechampine.com/us/internal/ghost.(*Host).listen.func1()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:59 +0x53

Goroutine 138 (running) created at:
  lukechampine.com/us/internal/ghost.(*Host).listen()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:58 +0x5c
==================
==================
WARNING: DATA RACE
Read at 0x00c000ede008 by goroutine 53:
  lukechampine.com/us/internal/ghost.(*Host).rpcLock()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:289 +0x6e4
  lukechampine.com/us/internal/ghost.(*Host).rpcLock-fm()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:261 +0x4b
  lukechampine.com/us/internal/ghost.(*Host).handleConn()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:66 +0xaad
  lukechampine.com/us/internal/ghost.(*Host).listen.func1()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:59 +0x53

Previous write at 0x00c000ede008 by goroutine 138:
  lukechampine.com/us/internal/ghost.(*Host).rpcRead()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:657 +0x10d1
  lukechampine.com/us/internal/ghost.(*Host).rpcRead-fm()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:560 +0x4b
  lukechampine.com/us/internal/ghost.(*Host).handleConn()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:66 +0xaad
  lukechampine.com/us/internal/ghost.(*Host).listen.func1()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:59 +0x53

Goroutine 53 (running) created at:
  lukechampine.com/us/internal/ghost.(*Host).listen()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:58 +0x5c

Goroutine 138 (running) created at:
  lukechampine.com/us/internal/ghost.(*Host).listen()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:58 +0x5c
==================
==================
WARNING: DATA RACE
Read at 0x00c000900008 by goroutine 106:
  lukechampine.com/us/internal/ghost.(*Host).rpcLock()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:289 +0x6e4
  lukechampine.com/us/internal/ghost.(*Host).rpcLock-fm()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:261 +0x4b
  lukechampine.com/us/internal/ghost.(*Host).handleConn()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:66 +0xaad
  lukechampine.com/us/internal/ghost.(*Host).listen.func1()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:59 +0x53

Previous write at 0x00c000900008 by goroutine 55:
  lukechampine.com/us/internal/ghost.(*Host).rpcRead()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:657 +0x10d1
  lukechampine.com/us/internal/ghost.(*Host).rpcRead-fm()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:560 +0x4b
  lukechampine.com/us/internal/ghost.(*Host).handleConn()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:66 +0xaad
  lukechampine.com/us/internal/ghost.(*Host).listen.func1()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:59 +0x53

Goroutine 106 (running) created at:
  lukechampine.com/us/internal/ghost.(*Host).listen()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:58 +0x5c

Goroutine 55 (running) created at:
  lukechampine.com/us/internal/ghost.(*Host).listen()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:58 +0x5c
==================
==================
WARNING: DATA RACE
Read at 0x00c000ede208 by goroutine 53:
  lukechampine.com/us/renterhost.(*objTransactionSignature).marshalledSize()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:788 +0xb2
  lukechampine.com/us/renterhost.(*RPCLockResponse).marshalledSize()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:415 +0x68
  lukechampine.com/us/renterhost.(*rpcResponse).marshalledSize()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:195 +0xe1
  lukechampine.com/us/renterhost.(*Session).writeMessage()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:121 +0x14f
  lukechampine.com/us/renterhost.(*Session).WriteResponse()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:216 +0x184
  lukechampine.com/us/internal/ghost.(*Host).rpcLock()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:292 +0x7f2
  lukechampine.com/us/internal/ghost.(*Host).rpcLock-fm()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:261 +0x4b
  lukechampine.com/us/internal/ghost.(*Host).handleConn()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:66 +0xaad
  lukechampine.com/us/internal/ghost.(*Host).listen.func1()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:59 +0x53

Previous write at 0x00c000ede208 by goroutine 138:
  lukechampine.com/us/internal/ghost.(*Host).rpcRead()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:658 +0x1192
  lukechampine.com/us/internal/ghost.(*Host).rpcRead-fm()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:560 +0x4b
  lukechampine.com/us/internal/ghost.(*Host).handleConn()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:66 +0xaad
  lukechampine.com/us/internal/ghost.(*Host).listen.func1()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:59 +0x53

Goroutine 53 (running) created at:
  lukechampine.com/us/internal/ghost.(*Host).listen()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:58 +0x5c

Goroutine 138 (running) created at:
  lukechampine.com/us/internal/ghost.(*Host).listen()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:58 +0x5c
==================
==================
WARNING: DATA RACE
Read at 0x00c000ede348 by goroutine 53:
  lukechampine.com/us/renterhost.(*objTransactionSignature).marshalledSize()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:788 +0xb2
  lukechampine.com/us/renterhost.(*RPCLockResponse).marshalledSize()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:415 +0x68
  lukechampine.com/us/renterhost.(*rpcResponse).marshalledSize()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:195 +0xe1
  lukechampine.com/us/renterhost.(*Session).writeMessage()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:121 +0x14f
  lukechampine.com/us/renterhost.(*Session).WriteResponse()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:216 +0x184
  lukechampine.com/us/internal/ghost.(*Host).rpcLock()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:292 +0x7f2
  lukechampine.com/us/internal/ghost.(*Host).rpcLock-fm()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:261 +0x4b
  lukechampine.com/us/internal/ghost.(*Host).handleConn()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:66 +0xaad
  lukechampine.com/us/internal/ghost.(*Host).listen.func1()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:59 +0x53

Previous write at 0x00c000ede348 by goroutine 138:
  lukechampine.com/us/internal/ghost.(*Host).rpcRead()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:659 +0x1213
  lukechampine.com/us/internal/ghost.(*Host).rpcRead-fm()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:560 +0x4b
  lukechampine.com/us/internal/ghost.(*Host).handleConn()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:66 +0xaad
  lukechampine.com/us/internal/ghost.(*Host).listen.func1()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:59 +0x53

Goroutine 53 (running) created at:
  lukechampine.com/us/internal/ghost.(*Host).listen()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:58 +0x5c

Goroutine 138 (running) created at:
  lukechampine.com/us/internal/ghost.(*Host).listen()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:58 +0x5c
==================
==================
WARNING: DATA RACE
Read at 0x00c00039c188 by goroutine 53:
  math/big.(*Int).Bits()
      /usr/local/Cellar/go/1.15.2/libexec/src/math/big/int.go:87 +0x67
  lukechampine.com/us/renterhost.(*objCurrency).marshalledSize()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:822 +0x5a
  lukechampine.com/us/renterhost.(*objSiacoinOutput).marshalledSize()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:909 +0x75
  lukechampine.com/us/renterhost.(*objFileContractRevision).marshalledSize()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:1017 +0x65
  lukechampine.com/us/renterhost.(*RPCLockResponse).marshalledSize()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:417 +0x137
  lukechampine.com/us/renterhost.(*rpcResponse).marshalledSize()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:195 +0xe1
  lukechampine.com/us/renterhost.(*Session).writeMessage()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:121 +0x14f
  lukechampine.com/us/renterhost.(*Session).WriteResponse()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:216 +0x184
  lukechampine.com/us/internal/ghost.(*Host).rpcLock()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:292 +0x7f2
  lukechampine.com/us/internal/ghost.(*Host).rpcLock-fm()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:261 +0x4b
  lukechampine.com/us/internal/ghost.(*Host).handleConn()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:66 +0xaad
  lukechampine.com/us/internal/ghost.(*Host).listen.func1()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:59 +0x53

Previous write at 0x00c00039c188 by goroutine 138:
  lukechampine.com/us/internal/ghost.(*Host).rpcRead()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:624 +0x77b
  lukechampine.com/us/internal/ghost.(*Host).rpcRead-fm()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:560 +0x4b
  lukechampine.com/us/internal/ghost.(*Host).handleConn()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:66 +0xaad
  lukechampine.com/us/internal/ghost.(*Host).listen.func1()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:59 +0x53

Goroutine 53 (running) created at:
  lukechampine.com/us/internal/ghost.(*Host).listen()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:58 +0x5c

Goroutine 138 (running) created at:
  lukechampine.com/us/internal/ghost.(*Host).listen()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:58 +0x5c
==================
==================
WARNING: DATA RACE
Read at 0x00c0003480b0 by goroutine 53:
  lukechampine.com/us/renterhost.(*objCurrency).marshalledSize()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:827 +0xbb
  lukechampine.com/us/renterhost.(*objSiacoinOutput).marshalledSize()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:909 +0x75
  lukechampine.com/us/renterhost.(*objFileContractRevision).marshalledSize()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:1017 +0x65
  lukechampine.com/us/renterhost.(*RPCLockResponse).marshalledSize()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:417 +0x137
  lukechampine.com/us/renterhost.(*rpcResponse).marshalledSize()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:195 +0xe1
  lukechampine.com/us/renterhost.(*Session).writeMessage()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:121 +0x14f
  lukechampine.com/us/renterhost.(*Session).WriteResponse()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:216 +0x184
  lukechampine.com/us/internal/ghost.(*Host).rpcLock()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:292 +0x7f2
  lukechampine.com/us/internal/ghost.(*Host).rpcLock-fm()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:261 +0x4b
  lukechampine.com/us/internal/ghost.(*Host).handleConn()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:66 +0xaad
  lukechampine.com/us/internal/ghost.(*Host).listen.func1()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:59 +0x53

Previous write at 0x00c0003480b0 by goroutine 138:
  math/big.nat.setBytes()
      /usr/local/Cellar/go/1.15.2/libexec/src/math/big/nat.go:1530 +0x42b
  math/big.(*Int).SetBytes()
      /usr/local/Cellar/go/1.15.2/libexec/src/math/big/int.go:444 +0x109
  lukechampine.com/us/renterhost.(*objCurrency).unmarshalBuffer()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:856 +0x75
  lukechampine.com/us/renterhost.(*RPCReadRequest).unmarshalBuffer()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:487 +0x3e4
  lukechampine.com/us/renterhost.(*Session).readMessage()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:177 +0x7fb
  lukechampine.com/us/renterhost.(*Session).ReadRequest()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:204 +0xd5
  lukechampine.com/us/internal/ghost.(*Host).rpcRead()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:564 +0x124
  lukechampine.com/us/internal/ghost.(*Host).rpcRead-fm()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:560 +0x4b
  lukechampine.com/us/internal/ghost.(*Host).handleConn()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:66 +0xaad
  lukechampine.com/us/internal/ghost.(*Host).listen.func1()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:59 +0x53

Goroutine 53 (running) created at:
  lukechampine.com/us/internal/ghost.(*Host).listen()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:58 +0x5c

Goroutine 138 (running) created at:
  lukechampine.com/us/internal/ghost.(*Host).listen()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:58 +0x5c
==================
==================
WARNING: DATA RACE
Read at 0x00c0003ca308 by goroutine 53:
  math/big.(*Int).Bits()
      /usr/local/Cellar/go/1.15.2/libexec/src/math/big/int.go:87 +0x67
  lukechampine.com/us/renterhost.(*objCurrency).marshalledSize()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:822 +0x5a
  lukechampine.com/us/renterhost.(*objSiacoinOutput).marshalledSize()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:909 +0x119
  lukechampine.com/us/renterhost.(*objFileContractRevision).marshalledSize()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:1021 +0x109
  lukechampine.com/us/renterhost.(*RPCLockResponse).marshalledSize()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:417 +0x137
  lukechampine.com/us/renterhost.(*rpcResponse).marshalledSize()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:195 +0xe1
  lukechampine.com/us/renterhost.(*Session).writeMessage()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:121 +0x14f
  lukechampine.com/us/renterhost.(*Session).WriteResponse()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:216 +0x184
  lukechampine.com/us/internal/ghost.(*Host).rpcLock()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:292 +0x7f2
  lukechampine.com/us/internal/ghost.(*Host).rpcLock-fm()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:261 +0x4b
  lukechampine.com/us/internal/ghost.(*Host).handleConn()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:66 +0xaad
  lukechampine.com/us/internal/ghost.(*Host).listen.func1()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:59 +0x53

Previous write at 0x00c0003ca308 by goroutine 138:
  lukechampine.com/us/internal/ghost.(*Host).rpcRead()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:631 +0xa1b
  lukechampine.com/us/internal/ghost.(*Host).rpcRead-fm()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:560 +0x4b
  lukechampine.com/us/internal/ghost.(*Host).handleConn()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:66 +0xaad
  lukechampine.com/us/internal/ghost.(*Host).listen.func1()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:59 +0x53

Goroutine 53 (running) created at:
  lukechampine.com/us/internal/ghost.(*Host).listen()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:58 +0x5c

Goroutine 138 (running) created at:
  lukechampine.com/us/internal/ghost.(*Host).listen()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:58 +0x5c
==================
==================
WARNING: DATA RACE
Read at 0x00c0003480e0 by goroutine 53:
  lukechampine.com/us/renterhost.(*objCurrency).marshalledSize()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:827 +0xbb
  lukechampine.com/us/renterhost.(*objSiacoinOutput).marshalledSize()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:909 +0x119
  lukechampine.com/us/renterhost.(*objFileContractRevision).marshalledSize()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:1021 +0x109
  lukechampine.com/us/renterhost.(*RPCLockResponse).marshalledSize()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:417 +0x137
  lukechampine.com/us/renterhost.(*rpcResponse).marshalledSize()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:195 +0xe1
  lukechampine.com/us/renterhost.(*Session).writeMessage()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:121 +0x14f
  lukechampine.com/us/renterhost.(*Session).WriteResponse()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:216 +0x184
  lukechampine.com/us/internal/ghost.(*Host).rpcLock()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:292 +0x7f2
  lukechampine.com/us/internal/ghost.(*Host).rpcLock-fm()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:261 +0x4b
  lukechampine.com/us/internal/ghost.(*Host).handleConn()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:66 +0xaad
  lukechampine.com/us/internal/ghost.(*Host).listen.func1()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:59 +0x53

Previous write at 0x00c0003480e0 by goroutine 138:
  math/big.nat.setBytes()
      /usr/local/Cellar/go/1.15.2/libexec/src/math/big/nat.go:1530 +0x42b
  math/big.(*Int).SetBytes()
      /usr/local/Cellar/go/1.15.2/libexec/src/math/big/int.go:444 +0x109
  lukechampine.com/us/renterhost.(*objCurrency).unmarshalBuffer()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:856 +0x75
  lukechampine.com/us/renterhost.(*RPCReadRequest).unmarshalBuffer()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:491 +0x51b
  lukechampine.com/us/renterhost.(*Session).readMessage()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:177 +0x7fb
  lukechampine.com/us/renterhost.(*Session).ReadRequest()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:204 +0xd5
  lukechampine.com/us/internal/ghost.(*Host).rpcRead()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:564 +0x124
  lukechampine.com/us/internal/ghost.(*Host).rpcRead-fm()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:560 +0x4b
  lukechampine.com/us/internal/ghost.(*Host).handleConn()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:66 +0xaad
  lukechampine.com/us/internal/ghost.(*Host).listen.func1()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:59 +0x53

Goroutine 53 (running) created at:
  lukechampine.com/us/internal/ghost.(*Host).listen()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:58 +0x5c

Goroutine 138 (running) created at:
  lukechampine.com/us/internal/ghost.(*Host).listen()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:58 +0x5c
==================
==================
WARNING: DATA RACE
Read at 0x00c00039c1a0 by goroutine 53:
  runtime.slicecopy()
      /usr/local/Cellar/go/1.15.2/libexec/src/runtime/slice.go:246 +0x0
  bytes.(*Buffer).Write()
      /usr/local/Cellar/go/1.15.2/libexec/src/bytes/buffer.go:174 +0x147
  lukechampine.com/us/renterhost.(*objBuffer).write()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:50 +0x74
  lukechampine.com/us/renterhost.(*objSiacoinOutput).marshalBuffer()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:914 +0x50
  lukechampine.com/us/renterhost.(*objFileContractRevision).marshalBuffer()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:1036 +0x1e4
  lukechampine.com/us/renterhost.(*RPCLockResponse).marshalBuffer()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:423 +0xa4
  lukechampine.com/us/renterhost.(*rpcResponse).marshalBuffer()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:203 +0xd4
  lukechampine.com/us/renterhost.(*Session).writeMessage()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:131 +0x33a
  lukechampine.com/us/renterhost.(*Session).WriteResponse()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:216 +0x184
  lukechampine.com/us/internal/ghost.(*Host).rpcLock()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:292 +0x7f2
  lukechampine.com/us/internal/ghost.(*Host).rpcLock-fm()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:261 +0x4b
  lukechampine.com/us/internal/ghost.(*Host).handleConn()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:66 +0xaad
  lukechampine.com/us/internal/ghost.(*Host).listen.func1()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:59 +0x53

Previous write at 0x00c00039c1a0 by goroutine 138:
  lukechampine.com/us/internal/ghost.(*Host).rpcRead()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:624 +0x77b
  lukechampine.com/us/internal/ghost.(*Host).rpcRead-fm()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:560 +0x4b
  lukechampine.com/us/internal/ghost.(*Host).handleConn()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:66 +0xaad
  lukechampine.com/us/internal/ghost.(*Host).listen.func1()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:59 +0x53

Goroutine 53 (running) created at:
  lukechampine.com/us/internal/ghost.(*Host).listen()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:58 +0x5c

Goroutine 138 (running) created at:
  lukechampine.com/us/internal/ghost.(*Host).listen()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:58 +0x5c
==================
==================
WARNING: DATA RACE
Read at 0x00c0003ca320 by goroutine 53:
  runtime.slicecopy()
      /usr/local/Cellar/go/1.15.2/libexec/src/runtime/slice.go:246 +0x0
  bytes.(*Buffer).Write()
      /usr/local/Cellar/go/1.15.2/libexec/src/bytes/buffer.go:174 +0x147
  lukechampine.com/us/renterhost.(*objBuffer).write()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:50 +0x74
  lukechampine.com/us/renterhost.(*objSiacoinOutput).marshalBuffer()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:914 +0x50
  lukechampine.com/us/renterhost.(*objFileContractRevision).marshalBuffer()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:1040 +0x2a4
  lukechampine.com/us/renterhost.(*RPCLockResponse).marshalBuffer()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:423 +0xa4
  lukechampine.com/us/renterhost.(*rpcResponse).marshalBuffer()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:203 +0xd4
  lukechampine.com/us/renterhost.(*Session).writeMessage()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:131 +0x33a
  lukechampine.com/us/renterhost.(*Session).WriteResponse()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:216 +0x184
  lukechampine.com/us/internal/ghost.(*Host).rpcLock()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:292 +0x7f2
  lukechampine.com/us/internal/ghost.(*Host).rpcLock-fm()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:261 +0x4b
  lukechampine.com/us/internal/ghost.(*Host).handleConn()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:66 +0xaad
  lukechampine.com/us/internal/ghost.(*Host).listen.func1()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:59 +0x53

Previous write at 0x00c0003ca320 by goroutine 138:
  lukechampine.com/us/internal/ghost.(*Host).rpcRead()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:631 +0xa1b
  lukechampine.com/us/internal/ghost.(*Host).rpcRead-fm()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:560 +0x4b
  lukechampine.com/us/internal/ghost.(*Host).handleConn()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:66 +0xaad
  lukechampine.com/us/internal/ghost.(*Host).listen.func1()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:59 +0x53

Goroutine 53 (running) created at:
  lukechampine.com/us/internal/ghost.(*Host).listen()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:58 +0x5c

Goroutine 138 (running) created at:
  lukechampine.com/us/internal/ghost.(*Host).listen()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:58 +0x5c
==================
==================
WARNING: DATA RACE
Read at 0x00c00017a340 by goroutine 106:
  runtime.slicecopy()
      /usr/local/Cellar/go/1.15.2/libexec/src/runtime/slice.go:246 +0x0
  bytes.(*Buffer).Write()
      /usr/local/Cellar/go/1.15.2/libexec/src/bytes/buffer.go:174 +0x147
  lukechampine.com/us/renterhost.(*objBuffer).write()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:50 +0x73
  lukechampine.com/us/renterhost.(*objBuffer).writePrefixedBytes()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:122 +0x4c
  lukechampine.com/us/renterhost.(*objTransactionSignature).marshalBuffer()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:796 +0x124
  lukechampine.com/us/renterhost.(*RPCLockResponse).marshalBuffer()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:426 +0x124
  lukechampine.com/us/renterhost.(*rpcResponse).marshalBuffer()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:203 +0xd4
  lukechampine.com/us/renterhost.(*Session).writeMessage()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:131 +0x33a
  lukechampine.com/us/renterhost.(*Session).WriteResponse()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:216 +0x184
  lukechampine.com/us/internal/ghost.(*Host).rpcLock()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:292 +0x7f2
  lukechampine.com/us/internal/ghost.(*Host).rpcLock-fm()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:261 +0x4b
  lukechampine.com/us/internal/ghost.(*Host).handleConn()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:66 +0xaad
  lukechampine.com/us/internal/ghost.(*Host).listen.func1()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:59 +0x53

Previous write at 0x00c00017a340 by goroutine 55:
  runtime.slicecopy()
      /usr/local/Cellar/go/1.15.2/libexec/src/runtime/slice.go:246 +0x0
  bytes.(*Buffer).Read()
      /usr/local/Cellar/go/1.15.2/libexec/src/bytes/buffer.go:306 +0x209
  io.ReadAtLeast()
      /usr/local/Cellar/go/1.15.2/libexec/src/io/io.go:314 +0x9c
  io.ReadFull()
      /usr/local/Cellar/go/1.15.2/libexec/src/io/io.go:333 +0x95
  lukechampine.com/us/renterhost.(*objBuffer).read()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:57 +0xaa
  lukechampine.com/us/renterhost.(*objBuffer).readPrefixedBytes()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:127 +0x90
  lukechampine.com/us/renterhost.(*RPCReadRequest).unmarshalBuffer()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:493 +0x57a
  lukechampine.com/us/renterhost.(*Session).readMessage()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:177 +0x7fb
  lukechampine.com/us/renterhost.(*Session).ReadRequest()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:204 +0xd5
  lukechampine.com/us/internal/ghost.(*Host).rpcRead()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:564 +0x124
  lukechampine.com/us/internal/ghost.(*Host).rpcRead-fm()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:560 +0x4b
  lukechampine.com/us/internal/ghost.(*Host).handleConn()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:66 +0xaad
  lukechampine.com/us/internal/ghost.(*Host).listen.func1()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:59 +0x53

Goroutine 106 (running) created at:
  lukechampine.com/us/internal/ghost.(*Host).listen()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:58 +0x5c

Goroutine 55 (running) created at:
  lukechampine.com/us/internal/ghost.(*Host).listen()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:58 +0x5c
==================
==================
WARNING: DATA RACE
Read at 0x00c000be6180 by goroutine 53:
  runtime.slicecopy()
      /usr/local/Cellar/go/1.15.2/libexec/src/runtime/slice.go:246 +0x0
  bytes.(*Buffer).Write()
      /usr/local/Cellar/go/1.15.2/libexec/src/bytes/buffer.go:174 +0x147
  lukechampine.com/us/renterhost.(*objBuffer).write()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:50 +0x73
  lukechampine.com/us/renterhost.(*objBuffer).writePrefixedBytes()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:122 +0x4c
  lukechampine.com/us/renterhost.(*objTransactionSignature).marshalBuffer()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:796 +0x124
  lukechampine.com/us/renterhost.(*RPCLockResponse).marshalBuffer()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:426 +0x124
  lukechampine.com/us/renterhost.(*rpcResponse).marshalBuffer()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:203 +0xd4
  lukechampine.com/us/renterhost.(*Session).writeMessage()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:131 +0x33a
  lukechampine.com/us/renterhost.(*Session).WriteResponse()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:216 +0x184
  lukechampine.com/us/internal/ghost.(*Host).rpcLock()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:292 +0x7f2
  lukechampine.com/us/internal/ghost.(*Host).rpcLock-fm()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:261 +0x4b
  lukechampine.com/us/internal/ghost.(*Host).handleConn()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:66 +0xaad
  lukechampine.com/us/internal/ghost.(*Host).listen.func1()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:59 +0x53

Previous write at 0x00c000be6180 by goroutine 138:
  runtime.slicecopy()
      /usr/local/Cellar/go/1.15.2/libexec/src/runtime/slice.go:246 +0x0
  bytes.(*Buffer).Read()
      /usr/local/Cellar/go/1.15.2/libexec/src/bytes/buffer.go:306 +0x209
  io.ReadAtLeast()
      /usr/local/Cellar/go/1.15.2/libexec/src/io/io.go:314 +0x9c
  io.ReadFull()
      /usr/local/Cellar/go/1.15.2/libexec/src/io/io.go:333 +0x95
  lukechampine.com/us/renterhost.(*objBuffer).read()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:57 +0xaa
  lukechampine.com/us/renterhost.(*objBuffer).readPrefixedBytes()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:127 +0x90
  lukechampine.com/us/renterhost.(*RPCReadRequest).unmarshalBuffer()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:493 +0x57a
  lukechampine.com/us/renterhost.(*Session).readMessage()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:177 +0x7fb
  lukechampine.com/us/renterhost.(*Session).ReadRequest()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:204 +0xd5
  lukechampine.com/us/internal/ghost.(*Host).rpcRead()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:564 +0x124
  lukechampine.com/us/internal/ghost.(*Host).rpcRead-fm()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:560 +0x4b
  lukechampine.com/us/internal/ghost.(*Host).handleConn()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:66 +0xaad
  lukechampine.com/us/internal/ghost.(*Host).listen.func1()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:59 +0x53

Goroutine 53 (running) created at:
  lukechampine.com/us/internal/ghost.(*Host).listen()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:58 +0x5c

Goroutine 138 (running) created at:
  lukechampine.com/us/internal/ghost.(*Host).listen()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:58 +0x5c
==================
==================
WARNING: DATA RACE
Read at 0x00c00017a380 by goroutine 106:
  runtime.slicecopy()
      /usr/local/Cellar/go/1.15.2/libexec/src/runtime/slice.go:246 +0x0
  bytes.(*Buffer).Write()
      /usr/local/Cellar/go/1.15.2/libexec/src/bytes/buffer.go:174 +0x147
  lukechampine.com/us/renterhost.(*objBuffer).write()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:50 +0x73
  lukechampine.com/us/renterhost.(*objBuffer).writePrefixedBytes()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:122 +0x4c
  lukechampine.com/us/renterhost.(*objTransactionSignature).marshalBuffer()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:796 +0x124
  lukechampine.com/us/renterhost.(*RPCLockResponse).marshalBuffer()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:426 +0x124
  lukechampine.com/us/renterhost.(*rpcResponse).marshalBuffer()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:203 +0xd4
  lukechampine.com/us/renterhost.(*Session).writeMessage()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:131 +0x33a
  lukechampine.com/us/renterhost.(*Session).WriteResponse()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:216 +0x184
  lukechampine.com/us/internal/ghost.(*Host).rpcLock()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:292 +0x7f2
  lukechampine.com/us/internal/ghost.(*Host).rpcLock-fm()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:261 +0x4b
  lukechampine.com/us/internal/ghost.(*Host).handleConn()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:66 +0xaad
  lukechampine.com/us/internal/ghost.(*Host).listen.func1()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:59 +0x53

Previous write at 0x00c00017a380 by goroutine 55:
  runtime.slicecopy()
      /usr/local/Cellar/go/1.15.2/libexec/src/runtime/slice.go:246 +0x0
  lukechampine.com/us/ed25519hash.sign()
      /Users/junpei/src/github.com/lukechampine/us/ed25519hash/ed25519.go:96 +0x487
  lukechampine.com/us/ed25519hash.Sign()
      /Users/junpei/src/github.com/lukechampine/us/ed25519hash/ed25519.go:56 +0x1065
  lukechampine.com/us/internal/ghost.(*Host).rpcRead()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:656 +0xf0e
  lukechampine.com/us/internal/ghost.(*Host).rpcRead-fm()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:560 +0x4b
  lukechampine.com/us/internal/ghost.(*Host).handleConn()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:66 +0xaad
  lukechampine.com/us/internal/ghost.(*Host).listen.func1()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:59 +0x53

Goroutine 106 (running) created at:
  lukechampine.com/us/internal/ghost.(*Host).listen()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:58 +0x5c

Goroutine 55 (running) created at:
  lukechampine.com/us/internal/ghost.(*Host).listen()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:58 +0x5c
==================
==================
WARNING: DATA RACE
Read at 0x00c000be61c0 by goroutine 53:
  runtime.slicecopy()
      /usr/local/Cellar/go/1.15.2/libexec/src/runtime/slice.go:246 +0x0
  bytes.(*Buffer).Write()
      /usr/local/Cellar/go/1.15.2/libexec/src/bytes/buffer.go:174 +0x147
  lukechampine.com/us/renterhost.(*objBuffer).write()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:50 +0x73
  lukechampine.com/us/renterhost.(*objBuffer).writePrefixedBytes()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:122 +0x4c
  lukechampine.com/us/renterhost.(*objTransactionSignature).marshalBuffer()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:796 +0x124
  lukechampine.com/us/renterhost.(*RPCLockResponse).marshalBuffer()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:426 +0x124
  lukechampine.com/us/renterhost.(*rpcResponse).marshalBuffer()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:203 +0xd4
  lukechampine.com/us/renterhost.(*Session).writeMessage()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:131 +0x33a
  lukechampine.com/us/renterhost.(*Session).WriteResponse()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:216 +0x184
  lukechampine.com/us/internal/ghost.(*Host).rpcLock()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:292 +0x7f2
  lukechampine.com/us/internal/ghost.(*Host).rpcLock-fm()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:261 +0x4b
  lukechampine.com/us/internal/ghost.(*Host).handleConn()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:66 +0xaad
  lukechampine.com/us/internal/ghost.(*Host).listen.func1()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:59 +0x53

Previous write at 0x00c000be61c0 by goroutine 138:
  runtime.slicecopy()
      /usr/local/Cellar/go/1.15.2/libexec/src/runtime/slice.go:246 +0x0
  lukechampine.com/us/ed25519hash.sign()
      /Users/junpei/src/github.com/lukechampine/us/ed25519hash/ed25519.go:96 +0x487
  lukechampine.com/us/ed25519hash.Sign()
      /Users/junpei/src/github.com/lukechampine/us/ed25519hash/ed25519.go:56 +0x1065
  lukechampine.com/us/internal/ghost.(*Host).rpcRead()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:656 +0xf0e
  lukechampine.com/us/internal/ghost.(*Host).rpcRead-fm()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:560 +0x4b
  lukechampine.com/us/internal/ghost.(*Host).handleConn()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:66 +0xaad
  lukechampine.com/us/internal/ghost.(*Host).listen.func1()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:59 +0x53

Goroutine 53 (running) created at:
  lukechampine.com/us/internal/ghost.(*Host).listen()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:58 +0x5c

Goroutine 138 (running) created at:
  lukechampine.com/us/internal/ghost.(*Host).listen()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:58 +0x5c
==================
==================
WARNING: DATA RACE
Read at 0x00c000be61e0 by goroutine 53:
  runtime.slicecopy()
      /usr/local/Cellar/go/1.15.2/libexec/src/runtime/slice.go:246 +0x0
  bytes.(*Buffer).Write()
      /usr/local/Cellar/go/1.15.2/libexec/src/bytes/buffer.go:174 +0x147
  lukechampine.com/us/renterhost.(*objBuffer).write()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:50 +0x73
  lukechampine.com/us/renterhost.(*objBuffer).writePrefixedBytes()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:122 +0x4c
  lukechampine.com/us/renterhost.(*objTransactionSignature).marshalBuffer()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:796 +0x124
  lukechampine.com/us/renterhost.(*RPCLockResponse).marshalBuffer()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:426 +0x124
  lukechampine.com/us/renterhost.(*rpcResponse).marshalBuffer()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:203 +0xd4
  lukechampine.com/us/renterhost.(*Session).writeMessage()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:131 +0x33a
  lukechampine.com/us/renterhost.(*Session).WriteResponse()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:216 +0x184
  lukechampine.com/us/internal/ghost.(*Host).rpcLock()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:292 +0x7f2
  lukechampine.com/us/internal/ghost.(*Host).rpcLock-fm()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:261 +0x4b
  lukechampine.com/us/internal/ghost.(*Host).handleConn()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:66 +0xaad
  lukechampine.com/us/internal/ghost.(*Host).listen.func1()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:59 +0x53

Previous write at 0x00c000be61e0 by goroutine 138:
  runtime.slicecopy()
      /usr/local/Cellar/go/1.15.2/libexec/src/runtime/slice.go:246 +0x0
  lukechampine.com/us/ed25519hash.sign()
      /Users/junpei/src/github.com/lukechampine/us/ed25519hash/ed25519.go:97 +0x4e9
  lukechampine.com/us/ed25519hash.Sign()
      /Users/junpei/src/github.com/lukechampine/us/ed25519hash/ed25519.go:56 +0x1065
  lukechampine.com/us/internal/ghost.(*Host).rpcRead()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:656 +0xf0e
  lukechampine.com/us/internal/ghost.(*Host).rpcRead-fm()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:560 +0x4b
  lukechampine.com/us/internal/ghost.(*Host).handleConn()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:66 +0xaad
  lukechampine.com/us/internal/ghost.(*Host).listen.func1()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:59 +0x53

Goroutine 53 (running) created at:
  lukechampine.com/us/internal/ghost.(*Host).listen()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:58 +0x5c

Goroutine 138 (running) created at:
  lukechampine.com/us/internal/ghost.(*Host).listen()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:58 +0x5c
==================
==================
WARNING: DATA RACE
Read at 0x00c00017a3a0 by goroutine 106:
  runtime.slicecopy()
      /usr/local/Cellar/go/1.15.2/libexec/src/runtime/slice.go:246 +0x0
  bytes.(*Buffer).Write()
      /usr/local/Cellar/go/1.15.2/libexec/src/bytes/buffer.go:174 +0x147
  lukechampine.com/us/renterhost.(*objBuffer).write()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:50 +0x73
  lukechampine.com/us/renterhost.(*objBuffer).writePrefixedBytes()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:122 +0x4c
  lukechampine.com/us/renterhost.(*objTransactionSignature).marshalBuffer()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:796 +0x124
  lukechampine.com/us/renterhost.(*RPCLockResponse).marshalBuffer()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:426 +0x124
  lukechampine.com/us/renterhost.(*rpcResponse).marshalBuffer()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/encoding.go:203 +0xd4
  lukechampine.com/us/renterhost.(*Session).writeMessage()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:131 +0x33a
  lukechampine.com/us/renterhost.(*Session).WriteResponse()
      /Users/junpei/src/github.com/lukechampine/us/renterhost/session.go:216 +0x184
  lukechampine.com/us/internal/ghost.(*Host).rpcLock()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:292 +0x7f2
  lukechampine.com/us/internal/ghost.(*Host).rpcLock-fm()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:261 +0x4b
  lukechampine.com/us/internal/ghost.(*Host).handleConn()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:66 +0xaad
  lukechampine.com/us/internal/ghost.(*Host).listen.func1()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:59 +0x53

Previous write at 0x00c00017a3a0 by goroutine 55:
  runtime.slicecopy()
      /usr/local/Cellar/go/1.15.2/libexec/src/runtime/slice.go:246 +0x0
  lukechampine.com/us/ed25519hash.sign()
      /Users/junpei/src/github.com/lukechampine/us/ed25519hash/ed25519.go:97 +0x4e9
  lukechampine.com/us/ed25519hash.Sign()
      /Users/junpei/src/github.com/lukechampine/us/ed25519hash/ed25519.go:56 +0x1065
  lukechampine.com/us/internal/ghost.(*Host).rpcRead()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:656 +0xf0e
  lukechampine.com/us/internal/ghost.(*Host).rpcRead-fm()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:560 +0x4b
  lukechampine.com/us/internal/ghost.(*Host).handleConn()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/session.go:66 +0xaad
  lukechampine.com/us/internal/ghost.(*Host).listen.func1()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:59 +0x53

Goroutine 106 (running) created at:
  lukechampine.com/us/internal/ghost.(*Host).listen()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:58 +0x5c

Goroutine 55 (running) created at:
  lukechampine.com/us/internal/ghost.(*Host).listen()
      /Users/junpei/src/github.com/lukechampine/us/internal/ghost/host.go:58 +0x5c
==================
--- FAIL: TestKVCancel (1.84s)
    testing.go:1042: race detected during execution of test

Looks like ghost package doesn't lock maps. But, it'd be better to fix it to make sure the cancellation doesn't have a race condition.

It looks like there are two races here:

  • renterhost.Session isn't thread-safe. Specifically, it has an internal err field that may be either set or checked by various methods, so calling those methods concurrently will cause a data race.
  • ghost doesn't protect contract access with a lock, so a renter can open two sessions that modify the same contract.

Both of these are relatively minor fixes.

Since we share a renterhost.Session with multiple goroutines, does it means it potentially misses error handling?

ghost was improperly sharing a session across goroutines, which is a bug. HostSet adds locking around sessions, which prevents them from being used concurrently.

I've resolved the issue for now by adding contract locks and only listening for RPCReadStop at the end of the RPC. This isn't really conformant with the spec, but it'll do for now. A larger ghost rewrite is coming soon anyway.

I just realized OverdriveChunkDownloader.DownloadChunkdoesn't return until the request times out if there is a host that doesn't respond to a contract lock request. In other words, this part could block up to 1 min. by default (5 min. in our case) regardless of whether the download succeeds:

sess, err := ocd.Hosts.tryAcquire(shard.HostKey)
if err == errHostAcquired && req.block {
sess, err = ocd.Hosts.acquire(shard.HostKey)
}

To avoid this, maybe lh.reconnect needs to implement a context-based cancellation.