Skip to content

Commit

Permalink
build: add windows support
Browse files Browse the repository at this point in the history
Turns out there's more differences in cgo bindings between macOS, Linux
and Windows. Instead of mucking around and trying to decipher the
madness, we shove all differentiating cgo calls into separate calls for
each platform.
  • Loading branch information
torkelrogstad authored and nchashch committed Jan 17, 2024
1 parent d87de93 commit c4cac72
Show file tree
Hide file tree
Showing 5 changed files with 384 additions and 123 deletions.
116 changes: 8 additions & 108 deletions drivechain/drivechain.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package drivechain

/*
#cgo LDFLAGS: ./drivechain/target/debug/libdrivechain_eth.a -ldl -lm
#include "./bindings.h"
*/
import "C"
Expand All @@ -22,7 +21,6 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/log"
)

const THIS_SIDECHAIN = 6
Expand Down Expand Up @@ -62,8 +60,6 @@ func Init(dbPath, host string, port uint16, rpcUser, rpcPassword string) error {
panic(fmt.Sprintf("treasury account: %s != actual treasury account: %s", TREASURY_ACCOUNT, actualTreasuryAccount))
}

cDbPath := C.CString(dbPath)

// Verify we're able to use the RPC credentials

ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
Expand Down Expand Up @@ -98,13 +94,7 @@ func Init(dbPath, host string, port uint16, rpcUser, rpcPassword string) error {
)
}

cHost := C.CString(host)
cRpcUser := C.CString(rpcUser)
cRpcPassword := C.CString(rpcPassword)
C.init(cDbPath, C.ulong(THIS_SIDECHAIN), cHost, C.ushort(port), cRpcUser, cRpcPassword)
C.free(unsafe.Pointer(cDbPath))
C.free(unsafe.Pointer(cRpcUser))
C.free(unsafe.Pointer(cRpcPassword))
initBmmEngine(dbPath, host, rpcUser, rpcPassword, port)

return nil
}
Expand Down Expand Up @@ -173,93 +163,16 @@ func GetDepositOutputs() ([]Deposit, error) {

// common.Hash here is for transaction hashes.
func ConnectBlock(deposits []Deposit, withdrawals map[common.Hash]Withdrawal, refunds []Refund, just_checking bool) bool {
depositsMemory := C.malloc(C.size_t(len(deposits)) * C.size_t(unsafe.Sizeof(C.Deposit{})))
depositsSlice := (*[1<<30 - 1]C.Deposit)(depositsMemory)
for i, deposit := range deposits {
cDeposit := C.Deposit{
address: C.CString(strings.ToLower(deposit.Address.String())),
amount: newUlong(deposit.Amount.Uint64()),
}
depositsSlice[i] = cDeposit
}
cDeposits := C.Deposits{
ptr: &depositsSlice[0],
len: C.ulong(len(deposits)),
}
withdrawalsMemory := C.malloc(C.size_t(len(withdrawals)) * C.size_t(unsafe.Sizeof(C.Withdrawal{})))
withdrawalsSlice := (*[1<<30 - 1]C.Withdrawal)(withdrawalsMemory)
{
i := 0
for id, w := range withdrawals {
log.Info(fmt.Sprintf("wtid = %s", id.Hex()))
cWithdrawal := C.Withdrawal{
id: C.CString(id.Hex()),
address: w.Address,
amount: newUlong(w.Amount.Uint64()),
fee: newUlong(w.Fee.Uint64()),
}
withdrawalsSlice[i] = cWithdrawal
i += 1
}
}
cWithdrawals := C.Withdrawals{
ptr: &withdrawalsSlice[0],
len: C.ulong(len(withdrawals)),
}
refundsMemory := C.malloc(C.size_t(len(refunds)) * C.size_t(unsafe.Sizeof(C.Refund{})))
refundsSlice := (*[1<<30 - 1]C.Refund)(refundsMemory)
for i, r := range refunds {
cRefund := C.Refund{
id: C.CString(r.Id.Hex()),
amount: newUlong(r.Amount.Uint64()),
}
refundsSlice[i] = cRefund
}
cRefunds := C.Refunds{
ptr: &refundsSlice[0],
len: C.ulong(len(refunds)),
}
cDeposits := newDeposits(deposits)
cWithdrawals := newWithdrawals(withdrawals)
cRefunds := newRefunds(refunds)
return bool(C.connect_block(cDeposits, cWithdrawals, cRefunds, C.bool(just_checking)))
}

func DisconnectBlock(deposits []Deposit, withdrawals []common.Hash, refunds []common.Hash, just_checking bool) bool {
depositsMemory := C.malloc(C.size_t(len(deposits)) * C.size_t(unsafe.Sizeof(C.Deposit{})))
depositsSlice := (*[1<<30 - 1]C.Deposit)(depositsMemory)
for i, deposit := range deposits {
cDeposit := C.Deposit{
address: C.CString(strings.ToLower(deposit.Address.String())),
amount: newUlong(deposit.Amount.Uint64()),
}
depositsSlice[i] = cDeposit
}
cDeposits := C.Deposits{
ptr: &depositsSlice[0],
len: C.ulong(len(deposits)),
}
withdrawalsMemory := C.malloc(C.size_t(len(withdrawals)) * C.size_t(unsafe.Sizeof(C.Withdrawal{})))
withdrawalsSlice := (*[1<<30 - 1]C.Withdrawal)(withdrawalsMemory)
for i, id := range withdrawals {
cWithdrawal := C.Withdrawal{
id: C.CString(id.Hex()),
}
withdrawalsSlice[i] = cWithdrawal
}
cWithdrawals := C.Withdrawals{
ptr: &withdrawalsSlice[0],
len: C.ulong(len(withdrawals)),
}
refundsMemory := C.malloc(C.size_t(len(refunds)) * C.size_t(unsafe.Sizeof(C.Refund{})))
refundsSlice := (*[1<<30 - 1]C.Refund)(refundsMemory)
for i, id := range refunds {
cRefund := C.Refund{
id: C.CString(id.Hex()),
}
refundsSlice[i] = cRefund
}
cRefunds := C.Refunds{
ptr: &refundsSlice[0],
len: C.ulong(len(refunds)),
}
cDeposits := newDeposits(deposits)
cWithdrawals := newWithdrawalsFromHash(withdrawals)
cRefunds := newRefundsFromHash(refunds)
return bool(C.disconnect_block(cDeposits, cWithdrawals, cRefunds, C.bool(just_checking)))
}

Expand All @@ -273,12 +186,7 @@ func FormatDepositAddress(address string) string {
}

func CreateDeposit(address common.Address, amount uint64, fee uint64) bool {
cAddress := C.CString(strings.ToLower(address.Hex()))
cAmount := newUlong(amount)
cFee := newUlong(fee)
result := C.create_deposit(cAddress, cAmount, cFee)
C.free(unsafe.Pointer(cAddress))
return bool(result)
return createDeposit(address, amount, fee)
}

const (
Expand Down Expand Up @@ -358,14 +266,6 @@ func FormatMainchainAddress(dest [MainchainAddressLength]C.uchar) string {
return address
}

func attemptBmm(criticalHash string, prevMainBlockHash string, amount uint64) {
cCriticalHash := C.CString(criticalHash)
cPrevMainBlockHash := C.CString(prevMainBlockHash)
C.attempt_bmm(cCriticalHash, cPrevMainBlockHash, newUlong(amount))
C.free(unsafe.Pointer(cCriticalHash))
C.free(unsafe.Pointer(cPrevMainBlockHash))
}

func AttemptBmm(header *types.Header, amount uint64) {
attemptBmm(header.Hash().Hex()[2:], header.PrevMainBlockHash.Hex()[2:], amount)
}
Expand Down
126 changes: 121 additions & 5 deletions drivechain/drivechain_darwin.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,126 @@
//go:build darwin
// +build darwin

package drivechain

/*
#cgo LDFLAGS: ./drivechain/target/debug/libdrivechain_eth.a -ldl -lm
#include "./bindings.h"
*/
import "C"
import (
"strings"
"unsafe"

"github.com/ethereum/go-ethereum/common"
)

func newDeposits(deposits []Deposit) C.Deposits {
depositsMemory := C.malloc(C.size_t(len(deposits)) * C.size_t(unsafe.Sizeof(C.Deposit{})))
depositsSlice := (*[1<<30 - 1]C.Deposit)(depositsMemory)
for i, deposit := range deposits {
depositsSlice[i] = C.Deposit{
address: C.CString(strings.ToLower(deposit.Amount.String())),
amount: C.ulonglong(deposit.Amount.Uint64()),
}
}
return C.Deposits{
ptr: &depositsSlice[0],
len: C.ulong(len(deposits)),
}
}

func newRefundsFromHash(refunds []common.Hash) C.Refunds {
refundsMemory := C.malloc(C.size_t(len(refunds)) * C.size_t(unsafe.Sizeof(C.Refund{})))
refundsSlice := (*[1<<30 - 1]C.Refund)(refundsMemory)
for i, id := range refunds {
cRefund := C.Refund{
id: C.CString(id.Hex()),
}
refundsSlice[i] = cRefund
}
return C.Refunds{
ptr: &refundsSlice[0],
len: C.ulong(len(refunds)),
}
}

func newRefunds(refunds []Refund) C.Refunds {
refundsMemory := C.malloc(C.size_t(len(refunds)) * C.size_t(unsafe.Sizeof(C.Refund{})))
refundsSlice := (*[1<<30 - 1]C.Refund)(refundsMemory)
for i, r := range refunds {
cRefund := C.Refund{
id: C.CString(r.Id.Hex()),
amount: C.ulonglong(r.Amount.Uint64()),
}
refundsSlice[i] = cRefund
}
return C.Refunds{
ptr: &refundsSlice[0],
len: C.ulong(len(refunds)),
}
}

func newWithdrawalsFromHash(withdrawals []common.Hash) C.Withdrawals {
withdrawalsMemory := C.malloc(C.size_t(len(withdrawals)) * C.size_t(unsafe.Sizeof(C.Withdrawal{})))
withdrawalsSlice := (*[1<<30 - 1]C.Withdrawal)(withdrawalsMemory)
for i, id := range withdrawals {
cWithdrawal := C.Withdrawal{
id: C.CString(id.Hex()),
}
withdrawalsSlice[i] = cWithdrawal
}

return C.Withdrawals{
ptr: &withdrawalsSlice[0],
len: C.ulong(len(withdrawals)),
}
}

func newWithdrawals(withdrawals map[common.Hash]Withdrawal) C.Withdrawals {
withdrawalsMemory := C.malloc(C.size_t(len(withdrawals)) * C.size_t(unsafe.Sizeof(C.Withdrawal{})))
withdrawalsSlice := (*[1<<30 - 1]C.Withdrawal)(withdrawalsMemory)
{
i := 0
for id, w := range withdrawals {
cWithdrawal := C.Withdrawal{
id: C.CString(id.Hex()),
address: w.Address,
amount: C.ulonglong(w.Amount.Uint64()),
fee: C.ulonglong(w.Fee.Uint64()),
}
withdrawalsSlice[i] = cWithdrawal
i += 1
}
}
return C.Withdrawals{
ptr: &withdrawalsSlice[0],
len: C.ulong(len(withdrawals)),
}
}

func createDeposit(address common.Address, amount uint64, fee uint64) bool {
cAddress := C.CString(strings.ToLower(address.Hex()))
cAmount := C.ulonglong(amount)
cFee := C.ulonglong(fee)
result := C.create_deposit(cAddress, cAmount, cFee)
C.free(unsafe.Pointer(cAddress))
return bool(result)
}

func attemptBmm(criticalHash string, prevMainBlockHash string, amount uint64) {
cCriticalHash := C.CString(criticalHash)
cPrevMainBlockHash := C.CString(prevMainBlockHash)
C.attempt_bmm(cCriticalHash, cPrevMainBlockHash, C.ulonglong(amount))
C.free(unsafe.Pointer(cCriticalHash))
C.free(unsafe.Pointer(cPrevMainBlockHash))
}

func initBmmEngine(dbPath, host, rpcUser, rpcPassword string, port uint16) {
cDbPath := C.CString(dbPath)
cHost := C.CString(host)
cRpcUser := C.CString(rpcUser)
cRpcPassword := C.CString(rpcPassword)

func newUlong(in uint64) C.ulonglong {
return C.ulonglong(in)
C.init(cDbPath, C.ulong(THIS_SIDECHAIN), cHost, C.ushort(port), cRpcUser, cRpcPassword)
C.free(unsafe.Pointer(cDbPath))
C.free(unsafe.Pointer(cRpcUser))
C.free(unsafe.Pointer(cRpcPassword))
}
Loading

0 comments on commit c4cac72

Please sign in to comment.