diff --git a/cmd/go-ouroboros-network/localtxsubmission.go b/cmd/go-ouroboros-network/localtxsubmission.go index 9d72b8e2..310acb6d 100644 --- a/cmd/go-ouroboros-network/localtxsubmission.go +++ b/cmd/go-ouroboros-network/localtxsubmission.go @@ -12,12 +12,6 @@ import ( "os" ) -type localTxSubmissionState struct { - submitResponse chan bool -} - -var localTxSubmitState localTxSubmissionState - type localTxSubmissionFlags struct { flagset *flag.FlagSet txFile string @@ -27,15 +21,12 @@ func newLocalTxSubmissionFlags() *localTxSubmissionFlags { f := &localTxSubmissionFlags{ flagset: flag.NewFlagSet("local-tx-submission", flag.ExitOnError), } - f.flagset.StringVar(&f.txFile, "tx-file", "", "path to the transaction file to submit") + f.flagset.StringVar(&f.txFile, "tx-file", "", "path to the JSON transaction file to submit") return f } func buildLocalTxSubmissionConfig() localtxsubmission.Config { - return localtxsubmission.Config{ - AcceptTxFunc: localTxSubmissionAcceptTxHandler, - RejectTxFunc: localTxSubmissionRejectTxHandler, - } + return localtxsubmission.Config{} } func testLocalTxSubmission(f *globalFlags) { @@ -46,8 +37,6 @@ func testLocalTxSubmission(f *globalFlags) { os.Exit(1) } - localTxSubmitState.submitResponse = make(chan bool) - conn := createClientConnection(f) errorChan := make(chan error) go func() { @@ -94,19 +83,5 @@ func testLocalTxSubmission(f *globalFlags) { fmt.Printf("Error submitting transaction: %s\n", err) os.Exit(1) } - - // Wait for response - <-localTxSubmitState.submitResponse -} - -func localTxSubmissionAcceptTxHandler() error { fmt.Print("The transaction was accepted\n") - localTxSubmitState.submitResponse <- true - return nil -} - -func localTxSubmissionRejectTxHandler(reasonCbor []byte) error { - fmt.Printf("The transaction was rejected (reason in hex-encoded CBOR): %#v\n", reasonCbor) - os.Exit(1) - return nil } diff --git a/docker-compose.yml b/docker-compose.yml index 2b209ac7..60586d25 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,9 +5,9 @@ volumes: services: cardano-node: - image: inputoutput/cardano-node:1.33.0 + image: ghcr.io/cloudstruct/cardano-node:1.35.4 environment: - NETWORK: ${CARDANO_NETWORK:-testnet} + NETWORK: ${CARDANO_NETWORK:-preview} ports: - 8081:3001 volumes: diff --git a/protocol/localtxsubmission/client.go b/protocol/localtxsubmission/client.go index b602d8cb..7b572bf4 100644 --- a/protocol/localtxsubmission/client.go +++ b/protocol/localtxsubmission/client.go @@ -3,16 +3,20 @@ package localtxsubmission import ( "fmt" "github.com/cloudstruct/go-ouroboros-network/protocol" + "sync" ) type Client struct { *protocol.Protocol - config *Config + config *Config + busyMutex sync.Mutex + submitResultChan chan error } func NewClient(protoOptions protocol.ProtocolOptions, cfg *Config) *Client { c := &Client{ - config: cfg, + config: cfg, + submitResultChan: make(chan error), } protoConfig := protocol.ProtocolConfig{ Name: PROTOCOL_NAME, @@ -44,28 +48,36 @@ func (c *Client) messageHandler(msg protocol.Message, isResponse bool) error { } func (c *Client) SubmitTx(eraId uint16, tx []byte) error { + c.busyMutex.Lock() + defer c.busyMutex.Unlock() msg := NewMsgSubmitTx(eraId, tx) - return c.SendMessage(msg) + if err := c.SendMessage(msg); err != nil { + return err + } + err := <-c.submitResultChan + return err } -func (c *Client) Done(tx interface{}) error { +func (c *Client) Stop() error { + c.busyMutex.Lock() + defer c.busyMutex.Unlock() msg := NewMsgDone() - return c.SendMessage(msg) + if err := c.SendMessage(msg); err != nil { + return err + } + return nil } func (c *Client) handleAcceptTx() error { - if c.config.AcceptTxFunc == nil { - return fmt.Errorf("received local-tx-submission AcceptTx message but no callback function is defined") - } - // Call the user callback function - return c.config.AcceptTxFunc() + c.submitResultChan <- nil + return nil } -func (c *Client) handleRejectTx(msgGeneric protocol.Message) error { - if c.config.RejectTxFunc == nil { - return fmt.Errorf("received local-tx-submission RejectTx message but no callback function is defined") +func (c *Client) handleRejectTx(msg protocol.Message) error { + msgRejectTx := msg.(*MsgRejectTx) + err := TransactionRejectedError{ + ReasonCbor: []byte(msgRejectTx.Reason), } - msg := msgGeneric.(*MsgRejectTx) - // Call the user callback function - return c.config.RejectTxFunc([]byte(msg.Reason)) + c.submitResultChan <- err + return nil } diff --git a/protocol/localtxsubmission/error.go b/protocol/localtxsubmission/error.go new file mode 100644 index 00000000..f1e1244b --- /dev/null +++ b/protocol/localtxsubmission/error.go @@ -0,0 +1,13 @@ +package localtxsubmission + +import ( + "fmt" +) + +type TransactionRejectedError struct { + ReasonCbor []byte +} + +func (e TransactionRejectedError) Error() string { + return fmt.Sprintf("transaction rejected: CBOR reason hex: %x", e.ReasonCbor) +} diff --git a/protocol/localtxsubmission/localtxsubmission.go b/protocol/localtxsubmission/localtxsubmission.go index a525ddbb..be3f0746 100644 --- a/protocol/localtxsubmission/localtxsubmission.go +++ b/protocol/localtxsubmission/localtxsubmission.go @@ -50,16 +50,10 @@ type LocalTxSubmission struct { type Config struct { SubmitTxFunc SubmitTxFunc - AcceptTxFunc AcceptTxFunc - RejectTxFunc RejectTxFunc - DoneFunc DoneFunc } // Callback function types type SubmitTxFunc func(interface{}) error -type AcceptTxFunc func() error -type RejectTxFunc func([]byte) error -type DoneFunc func() error func New(protoOptions protocol.ProtocolOptions, cfg *Config) *LocalTxSubmission { l := &LocalTxSubmission{ diff --git a/protocol/localtxsubmission/server.go b/protocol/localtxsubmission/server.go index 5d59159e..b2536473 100644 --- a/protocol/localtxsubmission/server.go +++ b/protocol/localtxsubmission/server.go @@ -53,9 +53,5 @@ func (s *Server) handleSubmitTx(msgGeneric protocol.Message) error { } func (s *Server) handleDone() error { - if s.config.DoneFunc == nil { - return fmt.Errorf("received local-tx-submission Done message but no callback function is defined") - } - // Call the user callback function - return s.config.DoneFunc() + return nil }