diff --git a/client/tools.go b/client/tools.go
new file mode 100644
index 0000000000000000000000000000000000000000..64c75e4c8952b70926d19c601aa34cd2f638347e
--- /dev/null
+++ b/client/tools.go
@@ -0,0 +1,59 @@
+package client
+
+import (
+	"container/list"
+	"errors"
+	"fmt"
+)
+
+// genesisID is the ID of the genesis message
+var genesisID = "1111111111111111111111111111111111111111111111111111111111111111"
+
+// PastConeExist checks that all of the messages in the the past cone of a message are existing on the node
+// down to the genesis. Returns the number of messages in the past cone as well.
+func (api *GoShimmerAPI) PastConeExist(messageID string) (bool, int, error) {
+	// create a new stack that hold messages to check
+	stack := list.New()
+	stack.PushBack(messageID)
+	// keep track of submitted checks (to not re-add something to the stack that is already in it)
+	// searching in double-linked list is quite expensive, but not in a map
+	submitted := make(map[string]bool)
+
+	var checkedMessageCount int
+
+	// process messages, try to request parents until we end up at the genesis
+	for stack.Len() > 0 {
+		checkedMessageCount++
+		// pop the first element from stack
+		currentMsgElement := stack.Front()
+		currentMsgID := currentMsgElement.Value.(string)
+		stack.Remove(currentMsgElement)
+
+		// ask node if it has it
+		response, err := api.FindMessageByID([]string{currentMsgID})
+		if err != nil {
+			return false, checkedMessageCount, errors.New(fmt.Sprintf("error while requesting %s message: %s", currentMsgID, err.Error()))
+		}
+
+		currentMsg := response.Messages[0]
+		// the first element in response.Messages is Messages{}, so its ID is empty if message doesn't exist on node
+		if currentMsg.ID == "" {
+			return false, checkedMessageCount, errors.New(fmt.Sprintf("message %s doesn't exist on node", currentMsgID))
+		}
+
+		// is it the genesis?
+		if currentMsg.BranchID == genesisID && currentMsg.TrunkID == genesisID {
+			continue
+		} else {
+			if !submitted[currentMsg.BranchID] {
+				stack.PushBack(currentMsg.BranchID)
+				submitted[currentMsg.BranchID] = true
+			}
+			if !submitted[currentMsg.TrunkID] {
+				stack.PushBack(currentMsg.TrunkID)
+				submitted[currentMsg.TrunkID] = true
+			}
+		}
+	}
+	return true, checkedMessageCount, nil
+}